diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index b660168b2..ef0a5409e 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -22,8 +22,15 @@ on: branches: - main push: - branches-ignore: - - 'dependabot/**' + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read jobs: build: @@ -48,10 +55,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 with: distribution: ${{ matrix.jdk }} java-version: ${{ matrix.java }} diff --git a/api/pom.xml b/api/pom.xml index 89f7bbba1..69678665c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -147,6 +147,12 @@ guava-testlib test + + org.slf4j + slf4j-nop + ${slf4j.version} + test + jakarta.servlet @@ -244,6 +250,13 @@ false + + org.apache.maven.plugins + maven-surefire-plugin + + true + + diff --git a/api/src/test/java/com/google/appengine/api/images/ImagesServiceImplTest.java b/api/src/test/java/com/google/appengine/api/images/ImagesServiceImplTest.java index 27bb5bc8b..bb0cef7c3 100644 --- a/api/src/test/java/com/google/appengine/api/images/ImagesServiceImplTest.java +++ b/api/src/test/java/com/google/appengine/api/images/ImagesServiceImplTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; import java.util.concurrent.ExecutionException; @@ -166,14 +167,16 @@ private void setupGrpcService(ImagesServiceGrpc.ImagesServiceImplBase serviceImp grpcCleanup.register(InProcessChannelBuilder.forName(serverName).directExecutor().build()); blockingStub = ImagesServiceGrpc.newBlockingStub(channel); futureStub = ImagesServiceGrpc.newFutureStub(channel); - when(mockGrpcImagesClient.getBlockingStub()).thenReturn(blockingStub); - when(mockGrpcImagesClient.getFutureStub()).thenReturn(futureStub); + lenient().when(mockGrpcImagesClient.getBlockingStub()).thenReturn(blockingStub); + lenient().when(mockGrpcImagesClient.getFutureStub()).thenReturn(futureStub); imagesService = new ImagesServiceImpl( mockEnvironmentProvider, mockGrpcImagesClient, null, mockBlobstoreReference); - when(mockEnvironmentProvider.getenv( - ImagesServiceFactoryImpl.USE_CUSTOM_IMAGES_GRPC_SERVICE_ENV)) + lenient() + .when( + mockEnvironmentProvider.getenv( + ImagesServiceFactoryImpl.USE_CUSTOM_IMAGES_GRPC_SERVICE_ENV)) .thenReturn("true"); } @@ -356,8 +359,10 @@ public void loadImageData_withLegacyBlobKey_failure() throws Exception { public void setUpGrpc(boolean useGrpc) throws Exception { ImagesServiceImpl.setStorageForTesting(mockStorage); - when(mockEnvironmentProvider.getenv( - ImagesServiceFactoryImpl.USE_CUSTOM_IMAGES_GRPC_SERVICE_ENV)) + lenient() + .when( + mockEnvironmentProvider.getenv( + ImagesServiceFactoryImpl.USE_CUSTOM_IMAGES_GRPC_SERVICE_ENV)) .thenReturn(Boolean.toString(useGrpc)); if (useGrpc) { @@ -373,8 +378,8 @@ public void setUpGrpc(boolean useGrpc) throws Exception { InProcessChannelBuilder.forName(serverName).directExecutor().build()); blockingStub = ImagesServiceGrpc.newBlockingStub(channel); futureStub = ImagesServiceGrpc.newFutureStub(channel); - when(mockGrpcImagesClient.getBlockingStub()).thenReturn(blockingStub); - when(mockGrpcImagesClient.getFutureStub()).thenReturn(futureStub); + lenient().when(mockGrpcImagesClient.getBlockingStub()).thenReturn(blockingStub); + lenient().when(mockGrpcImagesClient.getFutureStub()).thenReturn(futureStub); imagesService = new ImagesServiceImpl( diff --git a/api/src/test/java/com/google/appengine/api/mail/stdimpl/GMTransportTest.java b/api/src/test/java/com/google/appengine/api/mail/stdimpl/GMTransportTest.java index 5b5fdc863..cf01d681e 100644 --- a/api/src/test/java/com/google/appengine/api/mail/stdimpl/GMTransportTest.java +++ b/api/src/test/java/com/google/appengine/api/mail/stdimpl/GMTransportTest.java @@ -76,7 +76,6 @@ public void setUp() throws Exception { ApiProxy.setEnvironmentForCurrentThread(environment); Properties props = new Properties(); - props.put("mail.debug", "true"); session = Session.getInstance(props); } @@ -177,6 +176,7 @@ public void testSendMessage_unicodeBody() throws Exception { message.setReplyTo(new InternetAddress[] {replyTo}); message.setSubject(subject); message.setContent(stream, "text/plain; charset=utf-16"); + message.setHeader("Content-Transfer-Encoding", "8bit"); MailMessage msgProto = MailMessage.newBuilder() .addTo(to.toString()) @@ -308,6 +308,7 @@ public void testSendMessage_byteAttachment() throws Exception { multi.addBodyPart(body); body = new MimeBodyPart(); body.setContent(fileContents, "text/plain"); + body.setHeader("Content-Transfer-Encoding", "7bit"); body.setFileName(filename); multi.addBodyPart(body); message.setContent(multi); @@ -355,19 +356,23 @@ public void testSendMessage_nestedAttachment() throws Exception { multi.addBodyPart(body); body = new MimeBodyPart(); body.setContent(fileContents, "text/plain"); + body.setHeader("Content-Transfer-Encoding", "7bit"); body.setFileName(filenameOuter); multi.addBodyPart(body); MimeMultipart nested = new MimeMultipart(); body = new MimeBodyPart(); body.setContent(fileContents, "text/plain"); + body.setHeader("Content-Transfer-Encoding", "7bit"); body.setFileName(filenameNested1); nested.addBodyPart(body); body = new MimeBodyPart(); body.setContent(fileContents, "text/plain"); + body.setHeader("Content-Transfer-Encoding", "7bit"); body.setFileName(filenameNested2); nested.addBodyPart(body); body = new MimeBodyPart(); body.setContent(nested); + body.setHeader("Content-Transfer-Encoding", "7bit"); multi.addBodyPart(body); message.setContent(multi); MailMessage msgProto = diff --git a/api_dev/pom.xml b/api_dev/pom.xml index fd8d661ba..110896cfe 100644 --- a/api_dev/pom.xml +++ b/api_dev/pom.xml @@ -209,6 +209,12 @@ mockito-junit-jupiter test + + org.slf4j + slf4j-nop + ${slf4j.version} + test + jakarta.servlet jakarta.servlet-api @@ -246,6 +252,13 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + 2 + + diff --git a/api_dev/src/main/java/com/google/appengine/api/datastore/dev/LocalDatastoreService.java b/api_dev/src/main/java/com/google/appengine/api/datastore/dev/LocalDatastoreService.java index 56c6dabad..a2f41e2f2 100644 --- a/api_dev/src/main/java/com/google/appengine/api/datastore/dev/LocalDatastoreService.java +++ b/api_dev/src/main/java/com/google/appengine/api/datastore/dev/LocalDatastoreService.java @@ -135,6 +135,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReadWriteLock; @@ -157,6 +158,7 @@ public abstract class LocalDatastoreService { // "iteration 2". private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + private static final AtomicBoolean loggedInitInfo = new AtomicBoolean(false); static final double DEFAULT_DEADLINE_SECONDS = 30.0; static final double MAX_DEADLINE_SECONDS = DEFAULT_DEADLINE_SECONDS; @@ -522,9 +524,15 @@ public void init(File appDirectory, Clock clock, Map properties) costAnalysis = new LocalDatastoreCostAnalysis(LocalCompositeIndexManager.getInstance()); - logger.atInfo().log( - "Local Datastore initialized: Type: %s Storage: %s", - spannerBacked() ? "VNext" : "High Replication", noStorage ? "In-memory" : backingStore); + if (loggedInitInfo.compareAndSet(false, true)) { + logger.atInfo().log( + "Local Datastore initialized: Type: %s Storage: %s", + spannerBacked() ? "VNext" : "High Replication", noStorage ? "In-memory" : backingStore); + } else { + logger.atFine().log( + "Local Datastore initialized: Type: %s Storage: %s", + spannerBacked() ? "VNext" : "High Replication", noStorage ? "In-memory" : backingStore); + } } private static > T getEnumProperty( diff --git a/api_dev/src/main/java/com/google/appengine/api/images/dev/LocalImagesService.java b/api_dev/src/main/java/com/google/appengine/api/images/dev/LocalImagesService.java index 8efee69c0..2591d4133 100644 --- a/api_dev/src/main/java/com/google/appengine/api/images/dev/LocalImagesService.java +++ b/api_dev/src/main/java/com/google/appengine/api/images/dev/LocalImagesService.java @@ -66,6 +66,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.ImageTypeSpecifier; @@ -86,6 +87,7 @@ public final class LocalImagesService extends AbstractLocalRpcService { private static final GoogleLogger log = GoogleLogger.forEnclosingClass(); + private static final AtomicBoolean loggedMissingFormatsWarning = new AtomicBoolean(false); private String hostPrefix; /** @@ -120,22 +122,24 @@ public void init(LocalServiceContext context, Map properties) { Thread.currentThread().setContextClassLoader(oldLoader); } - String[] inputFormats = {"png", "jpg", "gif", "bmp", "ico", "tif", "webp"}; - String[] outputFormats = {"png", "jpg", "webp"}; - for (String format : inputFormats) { - if (!ImageIO.getImageReadersByFormatName(format).hasNext()) { - log.atWarning().log( - "No image reader found for format \"%s\". An ImageIO plugin must be installed to use" - + " this format with the DevAppServer.", - format); + if (loggedMissingFormatsWarning.compareAndSet(false, true)) { + String[] inputFormats = {"png", "jpg", "gif", "bmp", "ico", "tif", "webp"}; + String[] outputFormats = {"png", "jpg", "webp"}; + for (String format : inputFormats) { + if (!ImageIO.getImageReadersByFormatName(format).hasNext()) { + log.atWarning().log( + "No image reader found for format \"%s\". An ImageIO plugin must be installed to use" + + " this format with the DevAppServer.", + format); + } } - } - for (String format : outputFormats) { - if (!ImageIO.getImageWritersByFormatName(format).hasNext()) { - log.atWarning().log( - "No image writer found for format \"%s\". An ImageIO plugin must be installed to use" - + " this format with the DevAppServer.", - format); + for (String format : outputFormats) { + if (!ImageIO.getImageWritersByFormatName(format).hasNext()) { + log.atWarning().log( + "No image writer found for format \"%s\". An ImageIO plugin must be installed to use" + + " this format with the DevAppServer.", + format); + } } } diff --git a/api_dev/src/main/java/com/google/appengine/api/mail/dev/LocalMailService.java b/api_dev/src/main/java/com/google/appengine/api/mail/dev/LocalMailService.java index 2255204b4..1a503cbd9 100644 --- a/api_dev/src/main/java/com/google/appengine/api/mail/dev/LocalMailService.java +++ b/api_dev/src/main/java/com/google/appengine/api/mail/dev/LocalMailService.java @@ -38,7 +38,7 @@ /** * Stub implementation of the Google App Engine mail api. - * This implementation logs messages using a {@link Logger} associated with + * This implementation logs messages using a {@link java.util.logging.Logger} associated with * this class and keeps messages that were sent in memory. If you want to * access the list of sent messages you can get ahold of the registered * LocalMailService instance as follows: diff --git a/api_dev/src/main/java/com/google/appengine/api/search/dev/LocalSearchService.java b/api_dev/src/main/java/com/google/appengine/api/search/dev/LocalSearchService.java index 953dd36da..6a0a3cd04 100644 --- a/api_dev/src/main/java/com/google/appengine/api/search/dev/LocalSearchService.java +++ b/api_dev/src/main/java/com/google/appengine/api/search/dev/LocalSearchService.java @@ -60,6 +60,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; @@ -90,6 +91,7 @@ public class LocalSearchService extends AbstractLocalRpcService { public static final String USE_DIRECTORY = "LocalSearchService.useDirectory"; private static final GoogleLogger log = GoogleLogger.forEnclosingClass(); + private static final AtomicBoolean loggedCreatedInfo = new AtomicBoolean(false); /** Hash function for adding query fingerprints to cursors. */ private static final HashFunction CURSOR_HASH = Hashing.murmur3_32(1729); @@ -145,7 +147,11 @@ private static int decodeCursor(SearchServicePb.SearchParams params, String curs public LocalSearchService() { analyzer = new WordSeparatorAnalyzer(); - log.atInfo().log("Local search service created"); + if (loggedCreatedInfo.compareAndSet(false, true)) { + log.atInfo().log("Local search service created"); + } else { + log.atFine().log("Local search service created"); + } } // --- Local RPC service --- diff --git a/api_dev/src/main/java/com/google/appengine/api/taskqueue/dev/UrlFetchJob.java b/api_dev/src/main/java/com/google/appengine/api/taskqueue/dev/UrlFetchJob.java index ce8d1c7ef..5690d9042 100644 --- a/api_dev/src/main/java/com/google/appengine/api/taskqueue/dev/UrlFetchJob.java +++ b/api_dev/src/main/java/com/google/appengine/api/taskqueue/dev/UrlFetchJob.java @@ -43,7 +43,8 @@ /** * Quartz {@link Job} implementation that hits a url. The url to hit, the http method to invoke, * headers, and any data that should be sent as part of the request are all determined by the {@link - * TaskQueueAddRequest} contained in the job data. We delegate to {@link LocalURLFetchService} for + * TaskQueueAddRequest} contained in the job data. We delegate to {@link + * com.google.appengine.api.urlfetch.dev.LocalURLFetchService} for * the actual fetching. * *

{@link #initialize(LocalServerEnvironment, Clock)} must be called before the first invocation diff --git a/api_dev/src/main/java/com/google/appengine/api/users/dev/LocalUserService.java b/api_dev/src/main/java/com/google/appengine/api/users/dev/LocalUserService.java index dc7e81d40..021319404 100644 --- a/api_dev/src/main/java/com/google/appengine/api/users/dev/LocalUserService.java +++ b/api_dev/src/main/java/com/google/appengine/api/users/dev/LocalUserService.java @@ -33,7 +33,7 @@ import java.util.Map; /** - * {@local LocalUserService} creates URLs that point to {@link + * {@link LocalUserService} creates URLs that point to {@link * LocalLoginServlet} and {@link LocalLogoutServlet} when used within * the Development AppServer environment. * diff --git a/api_dev/src/main/java/com/google/appengine/tools/development/ContainerService.java b/api_dev/src/main/java/com/google/appengine/tools/development/ContainerService.java index a2b8f7436..1043590f4 100644 --- a/api_dev/src/main/java/com/google/appengine/tools/development/ContainerService.java +++ b/api_dev/src/main/java/com/google/appengine/tools/development/ContainerService.java @@ -71,7 +71,7 @@ LocalServerEnvironment configure(String devAppServerVersion, String address, int *

* Note that this provides access to the original delegate which was established by * the {@link DevAppServer}. Though this delegate is usually available by calling - * {@Link ApiProxy#getDelegate()} the delegate can be changed by the application so + * {@link ApiProxy#getDelegate()} the delegate can be changed by the application so * we keep this reference to the original. * * @param apiProxyDelegate diff --git a/api_dev/src/main/java/com/google/appengine/tools/development/testing/LocalCapabilitiesServiceTestConfig.java b/api_dev/src/main/java/com/google/appengine/tools/development/testing/LocalCapabilitiesServiceTestConfig.java index 405e7656a..c1ccfedd6 100644 --- a/api_dev/src/main/java/com/google/appengine/tools/development/testing/LocalCapabilitiesServiceTestConfig.java +++ b/api_dev/src/main/java/com/google/appengine/tools/development/testing/LocalCapabilitiesServiceTestConfig.java @@ -51,7 +51,7 @@ public void tearDown() { * Controls the state of a capability in testing mode. * * @param capability the {@link Capability} to change the status of - * @param status the {@CapabilityStatus} to set for the given Capability + * @param status the {@link CapabilityStatus} to set for the given Capability * @return {@code this} (for chaining) */ public LocalCapabilitiesServiceTestConfig setCapabilityStatus(Capability capability, diff --git a/api_dev/src/test/java/com/google/appengine/api/blobstore/BlobstoreServiceImplTest.java b/api_dev/src/test/java/com/google/appengine/api/blobstore/BlobstoreServiceImplTest.java index bf0403fdf..eb0c7c66d 100644 --- a/api_dev/src/test/java/com/google/appengine/api/blobstore/BlobstoreServiceImplTest.java +++ b/api_dev/src/test/java/com/google/appengine/api/blobstore/BlobstoreServiceImplTest.java @@ -163,9 +163,6 @@ public void testDelete_multiSuccess() throws Exception { DeleteBlobRequest requestProto = DeleteBlobRequest.newBuilder().addBlobKey("_foo1").addBlobKey("_foo2").build(); - when(delegate.makeSyncCall(any(), any(), any(), any())).thenReturn(new byte[0]); - - new BlobstoreServiceImpl().delete(new BlobKey("_foo1"), new BlobKey("_foo2")); when(delegate.makeSyncCall( same(ApiProxy.getCurrentEnvironment()), eq(BlobstoreServiceImpl.PACKAGE), @@ -173,6 +170,8 @@ public void testDelete_multiSuccess() throws Exception { eq(requestProto.toByteArray()))) .thenReturn(new byte[0]); + new BlobstoreServiceImpl().delete(new BlobKey("_foo1"), new BlobKey("_foo2")); + verify(delegate) .makeSyncCall( same(ApiProxy.getCurrentEnvironment()), diff --git a/api_dev/src/test/java/com/google/appengine/api/datastore/AdminDatastoreServiceTest.java b/api_dev/src/test/java/com/google/appengine/api/datastore/AdminDatastoreServiceTest.java index 0942e81aa..2a3f1149c 100644 --- a/api_dev/src/test/java/com/google/appengine/api/datastore/AdminDatastoreServiceTest.java +++ b/api_dev/src/test/java/com/google/appengine/api/datastore/AdminDatastoreServiceTest.java @@ -21,6 +21,7 @@ import static com.google.common.util.concurrent.Futures.immediateFuture; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.notNull; import static org.mockito.Mockito.when; @@ -89,7 +90,7 @@ public void setUp() throws Exception { new AsyncDatastoreServiceFactory() { @Override public AsyncDatastoreService getInstance(DatastoreServiceConfig config) { - when(delegate.getDatastoreServiceConfig()).thenReturn(config); + lenient().when(delegate.getDatastoreServiceConfig()).thenReturn(config); return delegate; } diff --git a/api_dev/src/test/java/com/google/appengine/api/datastore/DatastoreCallbacksTest.java b/api_dev/src/test/java/com/google/appengine/api/datastore/DatastoreCallbacksTest.java index 516e86508..60f30ed19 100644 --- a/api_dev/src/test/java/com/google/appengine/api/datastore/DatastoreCallbacksTest.java +++ b/api_dev/src/test/java/com/google/appengine/api/datastore/DatastoreCallbacksTest.java @@ -1412,7 +1412,6 @@ public void testPostLoad_Get_Batch_RollbackTxn() throws Exception { datastore.get(ImmutableList.of(yar.getKey(), yarChild.getKey())); verifyNoMoreInteractions(mock); // postLoad callback doesn't run until we call get() on the future. - assertThat(result.get()).containsExactly(yar.getKey(), yar, yarChild.getKey(), yarChild); doAnswer(checkContext(new PostLoadContext(txnProvider, txn, ImmutableList.of(yar, yarChild)))) .when(mock) .postLoad(any()); diff --git a/appengine_jsr107/src/test/java/com/google/appengine/api/memcache/jsr107cache/GCacheTest.java b/appengine_jsr107/src/test/java/com/google/appengine/api/memcache/jsr107cache/GCacheTest.java index c7eff80aa..b62c99126 100644 --- a/appengine_jsr107/src/test/java/com/google/appengine/api/memcache/jsr107cache/GCacheTest.java +++ b/appengine_jsr107/src/test/java/com/google/appengine/api/memcache/jsr107cache/GCacheTest.java @@ -207,7 +207,7 @@ public void testPutAll_addIfNotPresent_throws() { properties.put(GCacheFactory.THROW_ON_PUT_FAILURE, Boolean.TRUE); properties.put(GCacheFactory.SET_POLICY, ADD_ONLY_IF_NOT_PRESENT); Cache cache = new GCache(properties); - when(service.putAll(map, null, REPLACE_ONLY_IF_PRESENT)).thenReturn(failureSet); + when(service.putAll(map, null, ADD_ONLY_IF_NOT_PRESENT)).thenReturn(failureSet); assertThrows(GCacheException.class, () -> cache.putAll(map)); } diff --git a/appengine_testing_tests/pom.xml b/appengine_testing_tests/pom.xml index af9da780c..37bd357fb 100644 --- a/appengine_testing_tests/pom.xml +++ b/appengine_testing_tests/pom.xml @@ -68,6 +68,12 @@ javax.servlet-api test + + org.slf4j + slf4j-nop + ${slf4j.version} + test + @@ -82,8 +88,12 @@ maven-surefire-plugin - -Duser.timezone=CST + -Xshare:off + --enable-native-access=ALL-UNNAMED + ${surefire.unsafe.arg} + -Duser.timezone=America/Chicago --add-opens java.base/java.lang=ALL-UNNAMED + -javaagent:${org.mockito:mockito-core:jar} true @@ -105,7 +115,7 @@ maven-surefire-plugin - -Duser.timezone=CST + -Duser.timezone=America/Chicago diff --git a/applications/guestbook/pom.xml b/applications/guestbook/pom.xml index df054ba7a..e7d0b061f 100644 --- a/applications/guestbook/pom.xml +++ b/applications/guestbook/pom.xml @@ -97,10 +97,14 @@ 3.5.5 + -Xshare:off + --enable-native-access=ALL-UNNAMED + ${surefire.unsafe.arg} --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED + -javaagent:${org.mockito:mockito-core:jar} diff --git a/applications/guestbook_jakarta/pom.xml b/applications/guestbook_jakarta/pom.xml index 5dc8371bf..a56bf7a70 100644 --- a/applications/guestbook_jakarta/pom.xml +++ b/applications/guestbook_jakarta/pom.xml @@ -97,10 +97,14 @@ 3.5.5 + -Xshare:off + --enable-native-access=ALL-UNNAMED + ${surefire.unsafe.arg} --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED + -javaagent:${org.mockito:mockito-core:jar} diff --git a/applications/jaxrs/pom.xml b/applications/jaxrs/pom.xml index 90adb4798..a72ef3ea2 100644 --- a/applications/jaxrs/pom.xml +++ b/applications/jaxrs/pom.xml @@ -92,6 +92,9 @@ 3.5.5 + -Xshare:off + --enable-native-access=ALL-UNNAMED + ${surefire.unsafe.arg} --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED diff --git a/external/geronimo_javamail/pom.xml b/external/geronimo_javamail/pom.xml index ae9b5db60..477caf061 100644 --- a/external/geronimo_javamail/pom.xml +++ b/external/geronimo_javamail/pom.xml @@ -75,6 +75,13 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + true + + diff --git a/lib/tools_api/src/main/java/com/google/appengine/tools/admin/Application.java b/lib/tools_api/src/main/java/com/google/appengine/tools/admin/Application.java index f7baf9852..13a6cd8e5 100644 --- a/lib/tools_api/src/main/java/com/google/appengine/tools/admin/Application.java +++ b/lib/tools_api/src/main/java/com/google/appengine/tools/admin/Application.java @@ -1236,8 +1236,7 @@ private void compileJspJavaFiles( // Depending on the runtime, select the correct bytecode target for the jsp classes compilation. // If the runtime is unknown and forced (like java9), keep the default settings. // If the current JDK is older than the runtime, we fallback to the current JDK version. - optionList.addAll(Arrays.asList("-source", javaVersion)); - optionList.addAll(Arrays.asList("-target", javaVersion)); + optionList.addAll(Arrays.asList("--release", javaVersion, "-Xlint:-options")); Iterable compilationUnits = fileManager.getJavaFileObjectsFromFiles(files); diff --git a/pom.xml b/pom.xml index cceb56981..25f42c4ed 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,7 @@ 12.1.13 2.0.20 4.36.2 + https://oss.sonatype.org/content/repositories/google-snapshots/ sonatype-nexus-snapshots https://oss.sonatype.org/service/local/staging/deploy/maven2/ @@ -268,6 +269,15 @@ + + surefire-jdk24plus + + [24,) + + + --sun-misc-unsafe-memory-access=allow + + webtide-harbor-profile @@ -810,6 +820,9 @@ true + -Xshare:off + --enable-native-access=ALL-UNNAMED + ${surefire.unsafe.arg} --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio.charset=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED diff --git a/protobuf/api/capability_service.proto b/protobuf/api/capability_service.proto index 91a948399..0130f9d8b 100644 --- a/protobuf/api/capability_service.proto +++ b/protobuf/api/capability_service.proto @@ -28,7 +28,6 @@ package java.apphosting; import "capabilities.proto"; -option java_generic_services = true; // auto-added option java_package = "com.google.appengine.api.capabilities"; option java_outer_classname = "CapabilityServicePb"; diff --git a/protobuf/api/images_service.proto b/protobuf/api/images_service.proto index d61a5b2b2..685d131f1 100644 --- a/protobuf/api/images_service.proto +++ b/protobuf/api/images_service.proto @@ -22,7 +22,6 @@ syntax = "proto2"; // See: http://go/proto2-generic-services-default package java.apphosting; -option java_generic_services = true; // auto-added option java_package = "com.google.appengine.api.images"; option java_outer_classname = "ImagesServicePb"; diff --git a/protobuf/api/memcache_service.proto b/protobuf/api/memcache_service.proto index 0f0a99454..1208836f6 100644 --- a/protobuf/api/memcache_service.proto +++ b/protobuf/api/memcache_service.proto @@ -42,7 +42,6 @@ syntax = "proto2"; // See: http://go/proto2-generic-services-default package java.apphosting; -option java_generic_services = true; // auto-added option java_package = "com.google.appengine.api.memcache"; option java_outer_classname = "MemcacheServicePb"; diff --git a/protobuf/api/urlfetch_service.proto b/protobuf/api/urlfetch_service.proto index 69ab8fba2..1075e29a7 100644 --- a/protobuf/api/urlfetch_service.proto +++ b/protobuf/api/urlfetch_service.proto @@ -29,7 +29,6 @@ syntax = "proto2"; // See: http://go/proto2-generic-services-default package java.apphosting; -option java_generic_services = true; // auto-added option java_package = "com.google.appengine.api.urlfetch"; option java_outer_classname = "URLFetchServicePb"; diff --git a/runtime/impl/src/test/java/com/google/apphosting/runtime/ApiProxyImplTest.java b/runtime/impl/src/test/java/com/google/apphosting/runtime/ApiProxyImplTest.java index 3b2ec06ed..0eeceae9d 100644 --- a/runtime/impl/src/test/java/com/google/apphosting/runtime/ApiProxyImplTest.java +++ b/runtime/impl/src/test/java/com/google/apphosting/runtime/ApiProxyImplTest.java @@ -664,7 +664,7 @@ private void doCancellationTest( switch (signal) { case CANCEL: synchronized (futures) { - for (Future future : futures) { + for (Future future : new ArrayList<>(futures)) { future.cancel(true); } } diff --git a/runtime/impl/src/test/java/com/google/apphosting/runtime/TraceWriterMemoryTest.java b/runtime/impl/src/test/java/com/google/apphosting/runtime/TraceWriterMemoryTest.java index 1c7a28eff..9e7ee4a3a 100644 --- a/runtime/impl/src/test/java/com/google/apphosting/runtime/TraceWriterMemoryTest.java +++ b/runtime/impl/src/test/java/com/google/apphosting/runtime/TraceWriterMemoryTest.java @@ -42,12 +42,11 @@ public void traceWriterDoesNotLeak() throws Exception { GcFinalization.awaitFullGc(); createManyApiSpans(writer); GcFinalization.awaitFullGc(); - long freeAfterSecond = runtime.freeMemory(); + long usedAfterSecond = runtime.totalMemory() - runtime.freeMemory(); createManyApiSpans(writer); GcFinalization.awaitFullGc(); - long freeAfterThird = runtime.freeMemory(); - // TODO: why is it 100X bigger in Copybara than Blaze? - assertThat(freeAfterThird - freeAfterSecond).isLessThan(400_000_000L); + long usedAfterThird = runtime.totalMemory() - runtime.freeMemory(); + assertThat(usedAfterThird - usedAfterSecond).isLessThan(40_000_000L); } private TraceWriter createTraceWriter() { diff --git a/runtime/runtime_impl_jetty12/src/test/java/com/google/apphosting/runtime/jetty/FileSenderTest.java b/runtime/runtime_impl_jetty12/src/test/java/com/google/apphosting/runtime/jetty/FileSenderTest.java index 663f6abd3..4cc89e934 100644 --- a/runtime/runtime_impl_jetty12/src/test/java/com/google/apphosting/runtime/jetty/FileSenderTest.java +++ b/runtime/runtime_impl_jetty12/src/test/java/com/google/apphosting/runtime/jetty/FileSenderTest.java @@ -155,8 +155,6 @@ public void checkIfUnmodified_validHeaders() throws Exception { when(mockRequest.getHeader(HttpHeader.IF_MODIFIED_SINCE.asString())) .thenReturn("Thu, 1 Jan 1970 00:00:00 GMT"); when(mockRequest.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString())).thenReturn(0L); - when(mockRequest.getHeader(HttpHeader.IF_UNMODIFIED_SINCE.asString())) - .thenReturn("Thu, 1 Jan 1970 00:00:01 GMT"); when(mockRequest.getDateHeader(HttpHeader.IF_UNMODIFIED_SINCE.asString())).thenReturn(1000L); when(mockResource.lastModified()).thenReturn(Instant.ofEpochMilli(100L)); @@ -179,8 +177,6 @@ public void checkIfUnmodified_headerUnmodifedLessThanResource() throws Exception when(mockRequest.getHeader(HttpHeader.IF_MODIFIED_SINCE.asString())) .thenReturn("Thu, 1 Jan 1970 00:00:00 GMT"); when(mockRequest.getDateHeader(HttpHeader.IF_MODIFIED_SINCE.asString())).thenReturn(0L); - when(mockRequest.getHeader(HttpHeader.IF_UNMODIFIED_SINCE.asString())) - .thenReturn("Thu, 1 Jan 1970 00:00:00 GMT"); when(mockRequest.getDateHeader(HttpHeader.IF_UNMODIFIED_SINCE.asString())).thenReturn(0L); when(mockResource.lastModified()).thenReturn(Instant.ofEpochSecond(100L)); diff --git a/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java b/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java index 27eafaeff..2d1b9987e 100644 --- a/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java +++ b/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java @@ -164,7 +164,7 @@ public RemoteApiPb.Response handle(RemoteApiPb.Request request) { try { Thread.sleep(delayMs); } catch (InterruptedException e) { - throw new RuntimeException(e); + Thread.currentThread().interrupt(); } break; case ECHO_METHOD: diff --git a/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java b/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java index 7e86525ad..a43c374e4 100644 --- a/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java +++ b/runtime/runtime_impl_jetty121/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java @@ -28,6 +28,8 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -41,6 +43,9 @@ public class InterruptedApiCallTest extends HttpApiProxyImplTestBase { */ @Test public void interruptedApiCall() throws InterruptedException { + Logger apiProxyLogger = Logger.getLogger(ApiProxyImpl.class.getName()); + Level previousLevel = apiProxyLogger.getLevel(); + apiProxyLogger.setLevel(Level.SEVERE); AtomicBoolean stop = new AtomicBoolean(); Thread apiClientThread = null; try { @@ -51,6 +56,7 @@ public void interruptedApiCall() throws InterruptedException { apiClientThread.interrupt(); // Ensure it wakes up from any blocking call apiClientThread.join(); } + apiProxyLogger.setLevel(previousLevel); } } diff --git a/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java b/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java index 27eafaeff..2d1b9987e 100644 --- a/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java +++ b/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/HttpApiProxyImplTestBase.java @@ -164,7 +164,7 @@ public RemoteApiPb.Response handle(RemoteApiPb.Request request) { try { Thread.sleep(delayMs); } catch (InterruptedException e) { - throw new RuntimeException(e); + Thread.currentThread().interrupt(); } break; case ECHO_METHOD: diff --git a/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java b/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java index 7e86525ad..a43c374e4 100644 --- a/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java +++ b/runtime/runtime_impl_jetty9/src/test/java/com/google/apphosting/runtime/http/InterruptedApiCallTest.java @@ -28,6 +28,8 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -41,6 +43,9 @@ public class InterruptedApiCallTest extends HttpApiProxyImplTestBase { */ @Test public void interruptedApiCall() throws InterruptedException { + Logger apiProxyLogger = Logger.getLogger(ApiProxyImpl.class.getName()); + Level previousLevel = apiProxyLogger.getLevel(); + apiProxyLogger.setLevel(Level.SEVERE); AtomicBoolean stop = new AtomicBoolean(); Thread apiClientThread = null; try { @@ -51,6 +56,7 @@ public void interruptedApiCall() throws InterruptedException { apiClientThread.interrupt(); // Ensure it wakes up from any blocking call apiClientThread.join(); } + apiProxyLogger.setLevel(previousLevel); } } diff --git a/runtime/test/pom.xml b/runtime/test/pom.xml index c2cd5eae3..bc363599a 100644 --- a/runtime/test/pom.xml +++ b/runtime/test/pom.xml @@ -134,6 +134,12 @@ appengine-tools-sdk test + + org.slf4j + slf4j-nop + ${slf4j.version} + test + diff --git a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/ApiCallsTest.java b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/ApiCallsTest.java index 7aa56e90a..9f464c72f 100644 --- a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/ApiCallsTest.java +++ b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/ApiCallsTest.java @@ -200,9 +200,13 @@ private RuntimeContext startApp( RuntimeContext.Config.builder(apiServerFactory); config.setApplicationPath(appPath.toString()); config.launcherFlagsBuilder().add("--clone_max_outstanding_api_rpcs=" + CONCURRENT_REQUESTS); + ImmutableMap.Builder env = + ImmutableMap.builder() + .put("GAE_JAVA_OPTS", "-Ddisable_api_call_logging_in_apiproxy=true"); if (httpApi == HttpApi.JDK) { - config.setEnvironmentEntries(ImmutableMap.of("APPENGINE_API_CALLS_USING_JDK_CLIENT", "true")); + env.put("APPENGINE_API_CALLS_USING_JDK_CLIENT", "true"); } + config.setEnvironmentEntries(env.buildOrThrow()); return createRuntimeContext(config.build()); } diff --git a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/JavaRuntimeViaHttpBase.java b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/JavaRuntimeViaHttpBase.java index 44313258b..b6d435b73 100644 --- a/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/JavaRuntimeViaHttpBase.java +++ b/runtime/test/src/test/java/com/google/apphosting/runtime/jetty/JavaRuntimeViaHttpBase.java @@ -483,16 +483,22 @@ public Config build() { /** JVM flags needed for JDK above JDK8 */ static ImmutableList optionalFlags() { - return ImmutableList.of( - "-showversion", - "--add-opens", - "java.base/java.lang=ALL-UNNAMED", - "--add-opens", - "java.base/java.nio.charset=ALL-UNNAMED", - "--add-opens", - "java.base/java.util.concurrent=ALL-UNNAMED", - "--add-opens", - "java.logging/java.util.logging=ALL-UNNAMED"); + ImmutableList.Builder flags = + ImmutableList.builder() + .add( + "-showversion", + "--add-opens", + "java.base/java.lang=ALL-UNNAMED", + "--add-opens", + "java.base/java.nio.charset=ALL-UNNAMED", + "--add-opens", + "java.base/java.util.concurrent=ALL-UNNAMED", + "--add-opens", + "java.logging/java.util.logging=ALL-UNNAMED"); + if (Runtime.version().feature() >= 24) { + flags.add("--sun-misc-unsafe-memory-access=allow"); + } + return flags.build(); } public static boolean isPortAvailable(String host, int port) {