diff --git a/bom/application/pom.xml b/bom/application/pom.xml index d7f587f87c9e5..caf88c0b03aba 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -159,7 +159,7 @@ 3.2.0 4.3.0 3.1.2.Final - 11.8.2 + 11.9.0 3.0.4 4.29.1 @@ -180,7 +180,7 @@ 2.2.1 26.0.5 1.15.1 - 3.49.3 + 3.49.4 2.38.0 0.27.3 1.46.3 @@ -194,7 +194,7 @@ 2.24.3 1.3.1.Final 1.12.0 - 2.6.9.Final + 2.6.11.Final 0.1.18.Final 1.21.1 3.4.2 diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 7154b15edbbc7..5ebacfd6fa9e3 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -33,7 +33,7 @@ 1.0.0 2.5.13 - 4.12.0 + 4.13.0 3.26.4 2.0.3.Final 6.0.1 diff --git a/docs/src/main/asciidoc/observability-devservices-lgtm.adoc b/docs/src/main/asciidoc/observability-devservices-lgtm.adoc index 9d395bdf99e7e..e2359e58f7768 100644 --- a/docs/src/main/asciidoc/observability-devservices-lgtm.adoc +++ b/docs/src/main/asciidoc/observability-devservices-lgtm.adoc @@ -53,7 +53,7 @@ This is the most common way to output metrics from Micrometer and the default wa .pom.xml ---- - io.quarkiverse.micrometer.registry + io.quarkus quarkus-micrometer-registry-prometheus ---- @@ -61,7 +61,7 @@ This is the most common way to output metrics from Micrometer and the default wa [source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"] .build.gradle ---- -implementation("io.quarkiverse.micrometer.registry:quarkus-micrometer-registry-prometheus") +implementation("io.quarkus:quarkus-micrometer-registry-prometheus") ---- ==== Using the Micrometer OTLP registry diff --git a/extensions/liquibase/liquibase-common/pom.xml b/extensions/liquibase/liquibase-common/pom.xml index b311e906f0996..a51fb77d67840 100644 --- a/extensions/liquibase/liquibase-common/pom.xml +++ b/extensions/liquibase/liquibase-common/pom.xml @@ -11,6 +11,7 @@ 4.0.0 quarkus-liquibase-common + Quarkus - Liquibase - Common 999-SNAPSHOT diff --git a/independent-projects/parent/pom.xml b/independent-projects/parent/pom.xml index e4bf460c9d2ca..21e48c2bfd907 100644 --- a/independent-projects/parent/pom.xml +++ b/independent-projects/parent/pom.xml @@ -20,7 +20,7 @@ 3.4.0 3.6.0 3.2.1 - 3.4.1 + 3.5.0 3.14.0 3.8.1 3.1.4 diff --git a/integration-tests/gradle/src/main/resources/with-junit-properties-file/build.gradle b/integration-tests/gradle/src/main/resources/with-junit-properties-file/build.gradle new file mode 100644 index 0000000000000..4d5d34d764813 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/with-junit-properties-file/build.gradle @@ -0,0 +1,39 @@ +plugins { + id 'java' + id 'io.quarkus' + id 'application' +} + +repositories { + mavenLocal { + content { + includeGroupByRegex 'io.quarkus.*' + includeGroup 'org.hibernate.orm' + } + } + mavenCentral() +} + +dependencies { + implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") + implementation 'io.quarkus:quarkus-resteasy' + + testImplementation 'io.quarkus:quarkus-junit5' + testImplementation 'io.rest-assured:rest-assured' +} + +compileJava { + options.compilerArgs << '-parameters' +} + + +run { + // propagate the custom local maven repo, in case it's configured + if (System.properties.containsKey('maven.repo.local')) { + systemProperty 'maven.repo.local', System.properties.get('maven.repo.local') + } +} + +test { + systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager" +} diff --git a/integration-tests/gradle/src/main/resources/with-junit-properties-file/gradle.properties b/integration-tests/gradle/src/main/resources/with-junit-properties-file/gradle.properties new file mode 100644 index 0000000000000..5dd9298be1f1d --- /dev/null +++ b/integration-tests/gradle/src/main/resources/with-junit-properties-file/gradle.properties @@ -0,0 +1,5 @@ +quarkusPluginVersion=${project.version} +quarkusPlatformArtifactId=quarkus-bom +quarkusPluginId=io.quarkus +quarkusPlatformGroupId=io.quarkus +quarkusPlatformVersion=${project.version} \ No newline at end of file diff --git a/integration-tests/gradle/src/main/resources/with-junit-properties-file/settings.gradle b/integration-tests/gradle/src/main/resources/with-junit-properties-file/settings.gradle new file mode 100644 index 0000000000000..b58701a207d85 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/with-junit-properties-file/settings.gradle @@ -0,0 +1,11 @@ +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + mavenLocal() + } + plugins { + id "${quarkusPluginId}" version "${quarkusPluginVersion}" + } +} +rootProject.name='code-with-quarkus' diff --git a/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/main/java/org/acme/GreetingResource.java b/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/main/java/org/acme/GreetingResource.java new file mode 100644 index 0000000000000..244f294265375 --- /dev/null +++ b/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/main/java/org/acme/GreetingResource.java @@ -0,0 +1,16 @@ +package org.acme; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/hello") +public class GreetingResource { + + @GET + @Produces(MediaType.TEXT_PLAIN) + public String hello() { + return "Hello from Quarkus REST"; + } +} diff --git a/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/main/resources/junit-platform.properties b/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/main/resources/junit-platform.properties new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/test/java/org/acme/GreetingResourceTest.java b/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/test/java/org/acme/GreetingResourceTest.java new file mode 100644 index 0000000000000..c5f31938400af --- /dev/null +++ b/integration-tests/gradle/src/main/resources/with-junit-properties-file/src/test/java/org/acme/GreetingResourceTest.java @@ -0,0 +1,21 @@ +package org.acme; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +class GreetingResourceTest { + @Test + void testHelloEndpoint() { + given() + .when().get("/hello") + .then() + .statusCode(200) + .body(is("Hello from Quarkus REST")); + } + +} \ No newline at end of file diff --git a/integration-tests/gradle/src/test/java/io/quarkus/gradle/TestWithAppJunitPropertiesFileTest.java b/integration-tests/gradle/src/test/java/io/quarkus/gradle/TestWithAppJunitPropertiesFileTest.java new file mode 100644 index 0000000000000..03ec0c748c0f4 --- /dev/null +++ b/integration-tests/gradle/src/test/java/io/quarkus/gradle/TestWithAppJunitPropertiesFileTest.java @@ -0,0 +1,21 @@ +package io.quarkus.gradle; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.io.File; + +import org.junit.jupiter.api.Test; + +public class TestWithAppJunitPropertiesFileTest extends QuarkusGradleWrapperTestBase { + + @Test + public void shouldRunTestsSuccessfully() throws Exception { + + final File projectDir = getProjectDir("with-junit-properties-file"); + + BuildResult buildResult = runGradleWrapper(projectDir, "test"); + + assertThat(BuildResult.isSuccessful(buildResult.getTasks().get(":test"))).isTrue(); + + } +} diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusTestIT.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusTestIT.java index 72d44f24b7444..accdefaa13f30 100644 --- a/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusTestIT.java +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusTestIT.java @@ -229,4 +229,40 @@ public void testQuarkusTestWithConfigInTestProfile() assertThat(installInvocation.getExitCode()).isEqualTo(0); } + + /* + * This should perhaps be in a different project, see https://github.com/quarkusio/quarkus/issues/46667 + */ @Test + public void testQuarkusTestInProjectWithJUnitProperties() + throws MavenInvocationException, InterruptedException { + String sourceDir = "projects/test-tests-in-project-with-junit-properties-file"; + testDir = initProject(sourceDir, sourceDir + "-processed"); + RunningInvoker invoker = new RunningInvoker(testDir, false); + + MavenProcessInvocationResult installInvocation = invoker.execute( + List.of("clean", "verify", "-Dquarkus.analytics.disabled=true"), + Collections.emptyMap()); + assertThat(installInvocation.getProcess().waitFor(2, TimeUnit.MINUTES)).isTrue(); + assertThat(installInvocation.getExecutionException()).isNull(); + assertThat(installInvocation.getExitCode()).isEqualTo(0); + + } + + @Test + public void testQuarkusTestInProjectWithJUnitPropertiesContinuousTesting() + throws MavenInvocationException, FileNotFoundException { + // This test will fail if the test extension does not reset the TCCL properly + String sourceDir = "projects/test-tests-in-project-with-junit-properties-file"; + testDir = initProject(sourceDir, sourceDir + "-processed-devmode"); + + runAndCheck(); + + ContinuousTestingMavenTestUtils testingTestUtils = new ContinuousTestingMavenTestUtils(getPort()); + ContinuousTestingMavenTestUtils.TestStatus results = testingTestUtils.waitForNextCompletion(); + // This is a bit brittle when we add tests, but failures are often so catastrophic they're not even reported as failures, + // so we need to check the pass count explicitly + Assertions.assertEquals(0, results.getTestsFailed()); + Assertions.assertEquals(1, results.getTestsPassed()); + Assertions.assertEquals(0, results.getTestsSkipped()); + } } diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/pom.xml new file mode 100644 index 0000000000000..af5d6315bf22a --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/pom.xml @@ -0,0 +1,121 @@ + + + 4.0.0 + + org.acme + quarkus-test-test-profile + 1.0-SNAPSHOT + + + io.quarkus + quarkus-bom + @project.version@ + @project.version@ + ${compiler-plugin.version} + ${version.surefire.plugin} + ${maven.compiler.source} + ${maven.compiler.target} + UTF-8 + + + + + + \${quarkus.platform.group-id} + \${quarkus.platform.artifact-id} + \${quarkus.platform.version} + pom + import + + + + + + + io.quarkus + quarkus-rest + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + + + + maven-surefire-plugin + \${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + \${maven.home} + + + + + io.quarkus + quarkus-maven-plugin + \${quarkus-plugin.version} + + + + build + + + + + + + + + + + native + + + native + + + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + + \${native.surefire.skip} + + + + maven-failsafe-plugin + \${surefire-plugin.version} + + + + integration-test + verify + + + + \${project.build.directory}/\${project.build.finalName}-runner + org.jboss.logmanager.LogManager + \${maven.home} + + + + + + + + + + diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/HelloResource.java b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/HelloResource.java new file mode 100644 index 0000000000000..964fca6e759ad --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/HelloResource.java @@ -0,0 +1,22 @@ +package org.acme; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +import org.eclipse.microprofile.config.ConfigProvider; + +@Path("/hello") +public class HelloResource { + + @GET + @Produces(MediaType.TEXT_PLAIN) + public String hello() { + // This config access only works if the TCCL is set properly + String message = ConfigProvider.getConfig().getValue("greeting.message", String.class); + return message; + + } + +} diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/Main.java b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/Main.java new file mode 100644 index 0000000000000..56c82b37dff82 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/Main.java @@ -0,0 +1,18 @@ +package org.acme; + +import io.quarkus.runtime.Quarkus; +import io.quarkus.runtime.QuarkusApplication; +import io.quarkus.runtime.annotations.QuarkusMain; + +@QuarkusMain +public class Main implements QuarkusApplication { + + public static volatile String[] PARAMS; + + @Override + public int run(String... args) throws Exception { + PARAMS = args; + Quarkus.waitForExit(); + return 0; + } +} diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/MyApplication.java b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/MyApplication.java new file mode 100644 index 0000000000000..a6d66f8b9eda2 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/java/org/acme/MyApplication.java @@ -0,0 +1,9 @@ +package org.acme; + +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; + +@ApplicationPath("/app") +public class MyApplication extends Application { + +} diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/META-INF/resources/index.html b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/META-INF/resources/index.html new file mode 100644 index 0000000000000..36789577840ad --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/META-INF/resources/index.html @@ -0,0 +1,156 @@ + + + + + acme - 1.0-SNAPSHOT + + + + + + +
+
+

Congratulations, you have created a new Quarkus application.

+ +

Why do you see this?

+ +

This page is served by Quarkus. The source is in + src/main/resources/META-INF/resources/index.html.

+ +

What can I do from here?

+ +

If not already done, run the application in dev mode using: mvn quarkus:dev. +

+
    +
  • Add REST resources, Servlets, functions and other services in src/main/java.
  • +
  • Your static assets are located in src/main/resources/META-INF/resources.
  • +
  • Configure your application in src/main/resources/application.properties. +
  • +
+ +

Do you like Quarkus?

+

Go give it a star on GitHub.

+ +

How do I get rid of this page?

+

Just delete the src/main/resources/META-INF/resources/index.html file.

+
+
+
+

Application

+
    +
  • GroupId: org.acme
  • +
  • ArtifactId: acme
  • +
  • Version: 1.0-SNAPSHOT
  • +
  • Quarkus Version: 999-SNAPSHOT
  • +
+
+
+

Next steps

+ +
+
+
+ + + + \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/application.properties b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/application.properties new file mode 100644 index 0000000000000..74aea65cc4789 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/application.properties @@ -0,0 +1,2 @@ +quarkus.test.continuous-testing=enabled +greeting.message=Hello from Quarkus REST via config diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/junit-platform.properties b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/main/resources/junit-platform.properties new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/test/java/org/acme/HelloResourceTest.java b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/test/java/org/acme/HelloResourceTest.java new file mode 100644 index 0000000000000..22521f5cd6057 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/test-tests-in-project-with-junit-properties-file/src/test/java/org/acme/HelloResourceTest.java @@ -0,0 +1,23 @@ +package org.acme; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class HelloResourceTest { + + @Test + public void testHelloEndpoint() { + given() + .when() + .get("/app/hello") + .then() + .statusCode(200) + .body(is("Hello from Quarkus REST via config")); + } + +} diff --git a/pom.xml b/pom.xml index 6f6970793e253..27d57b1d09d6b 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ 3.25.5 ${protoc.version} ${protoc.version} - 2.56.0 + 2.58.0 0.27.0 diff --git a/relocations/generaterelocations.java b/relocations/generaterelocations.java index 909f2b119edd5..51f7f33270a93 100755 --- a/relocations/generaterelocations.java +++ b/relocations/generaterelocations.java @@ -49,6 +49,7 @@ public class generaterelocations implements Runnable { " 4.0.0\n" + // "\n" + // " %1$s\n" + // + " Quarkus - Relocations - %1$s\n" + // "\n" + // " \n" + // " \n" + // diff --git a/relocations/pom.xml b/relocations/pom.xml index 3d175281d8b13..fd4804fada0a4 100644 --- a/relocations/pom.xml +++ b/relocations/pom.xml @@ -11,7 +11,7 @@ 4.0.0 quarkus-relocations-parent - Quarkus - Relocations Parent + Quarkus - Relocations This is the parent of relocated artifacts, that are still released for compatibility reasons. pom diff --git a/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling-deployment/pom.xml b/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling-deployment/pom.xml index de349589a3389..40cbd95ff89c4 100644 --- a/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling-deployment/pom.xml +++ b/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling-deployment/pom.xml @@ -10,6 +10,7 @@ 4.0.0 quarkus-hibernate-search-orm-coordination-outbox-polling-deployment + Quarkus - Relocations - quarkus-hibernate-search-orm-coordination-outbox-polling-deployment diff --git a/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling/pom.xml b/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling/pom.xml index e4f7adaeba992..7b1895ed357f3 100644 --- a/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling/pom.xml +++ b/relocations/quarkus-hibernate-search-orm-coordination-outbox-polling/pom.xml @@ -10,6 +10,7 @@ 4.0.0 quarkus-hibernate-search-orm-coordination-outbox-polling + Quarkus - Relocations - quarkus-hibernate-search-orm-coordination-outbox-polling diff --git a/relocations/quarkus-webjars-locator-deployment/pom.xml b/relocations/quarkus-webjars-locator-deployment/pom.xml index acf6ae74bf5f7..6708de0b54d55 100644 --- a/relocations/quarkus-webjars-locator-deployment/pom.xml +++ b/relocations/quarkus-webjars-locator-deployment/pom.xml @@ -10,6 +10,7 @@ 4.0.0 quarkus-webjars-locator-deployment + Quarkus - Relocations - quarkus-webjars-locator-deployment diff --git a/relocations/quarkus-webjars-locator/pom.xml b/relocations/quarkus-webjars-locator/pom.xml index ce5e63c7d4c2c..a05083cdfd770 100644 --- a/relocations/quarkus-webjars-locator/pom.xml +++ b/relocations/quarkus-webjars-locator/pom.xml @@ -10,6 +10,7 @@ 4.0.0 quarkus-webjars-locator + Quarkus - Relocations - quarkus-webjars-locator diff --git a/test-framework/junit5-config/src/main/java/io/quarkus/test/config/ConfigLauncherSession.java b/test-framework/junit5-config/src/main/java/io/quarkus/test/config/ConfigLauncherSession.java index 4880037c6bc88..a8758bdc02280 100644 --- a/test-framework/junit5-config/src/main/java/io/quarkus/test/config/ConfigLauncherSession.java +++ b/test-framework/junit5-config/src/main/java/io/quarkus/test/config/ConfigLauncherSession.java @@ -17,8 +17,8 @@ public class ConfigLauncherSession implements LauncherSessionListener { @Override public void launcherSessionOpened(final LauncherSession session) { // Ideally the classloader would be correct when this is launched, - // but for gradle, test class loading happens faierly shortly after this is called, - // before the formal loading phase. To make that work, the TCCL has to be + // but for gradle, test class loading happens fairly shortly after this is called, + // before the formal loading phase. To make that work, the TCCL may have been // set to the FCL by the time this is called, even though we want config to live on the app classloader ClassLoader old = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); diff --git a/test-framework/junit5-config/src/main/resources/junit-platform.properties b/test-framework/junit5-config/src/main/resources/junit-platform.properties index 8f7d457a88a47..d24c3ed5820f5 100644 --- a/test-framework/junit5-config/src/main/resources/junit-platform.properties +++ b/test-framework/junit5-config/src/main/resources/junit-platform.properties @@ -1,3 +1,2 @@ junit.jupiter.extensions.autodetection.enabled=true junit.jupiter.testclass.order.default=io.quarkus.test.config.QuarkusClassOrderer -junit.platform.launcher.interceptors.enabled=true diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/launcher/CustomLauncherInterceptor.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/launcher/CustomLauncherInterceptor.java index 04668bc1b4ae1..61de19104e6d3 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/launcher/CustomLauncherInterceptor.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/launcher/CustomLauncherInterceptor.java @@ -2,11 +2,12 @@ import org.junit.platform.launcher.LauncherDiscoveryListener; import org.junit.platform.launcher.LauncherDiscoveryRequest; -import org.junit.platform.launcher.LauncherInterceptor; +import org.junit.platform.launcher.LauncherSession; +import org.junit.platform.launcher.LauncherSessionListener; import io.quarkus.test.junit.classloading.FacadeClassLoader; -public class CustomLauncherInterceptor implements LauncherDiscoveryListener, LauncherInterceptor { +public class CustomLauncherInterceptor implements LauncherDiscoveryListener, LauncherSessionListener { private static FacadeClassLoader facadeLoader = null; // Also use a static variable to store a 'first' starting state that we can reset to @@ -21,37 +22,30 @@ private static boolean isProductionModeTests() { } @Override - public T intercept(Invocation invocation) { - // Do not do any classloading dance for prod mode tests; - if (isProductionModeTests()) { - return invocation.proceed(); - - } else { - return actuallyIntercept(invocation); + public void launcherSessionOpened(LauncherSession session) { + /* + * For gradle, test class loading happens fairly shortly after this is called, + * before the formal discovery phase. So we need to intercept the TCCL + * Do not do any classloading dance for prod mode tests; + */ + if (!isProductionModeTests()) { + actuallyIntercept(); } } - private T actuallyIntercept(Invocation invocation) { + private void actuallyIntercept() { if (origCl == null) { origCl = Thread.currentThread() .getContextClassLoader(); } - ClassLoader currentCl = Thread.currentThread().getContextClassLoader(); - // Be aware, this method might be called more than once, for different kinds of invocations; especially for Gradle executions, the executions could happen before the TCCL gets constructed and set by JUnitTestRunner // We might not be in the same classloader as the Facade ClassLoader, so use a name comparison instead of an instanceof - if (true || currentCl == null - || (currentCl != facadeLoader && !currentCl.getClass().getName().equals(FacadeClassLoader.class.getName()))) { - initializeFacadeClassLoader(); - adjustContextClassLoader(); - return invocation.proceed(); + initializeFacadeClassLoader(); + adjustContextClassLoader(); - // It's tempting to tidy up in a finally block by resetting the TCCL, but the gradle tests - // do discovery 'between' invocation blocks, and outside the main + // It's tempting to tidy up in a finally block by resetting the TCCL, but the gradle tests + // do discovery 'between' invocation blocks, and outside the main - } else { - return invocation.proceed(); - } } // Make a facade classloader if needed, so that we can close it at the end of the launcher session @@ -68,12 +62,14 @@ private void initializeFacadeClassLoader() { facadeLoader = new FacadeClassLoader(currentCl); } } + } @Override public void launcherDiscoveryStarted(LauncherDiscoveryRequest request) { // Do not do any classloading dance for prod mode tests; if (!isProductionModeTests()) { + initializeFacadeClassLoader(); adjustContextClassLoader(); } @@ -92,24 +88,26 @@ private void adjustContextClassLoader() { @Override public void launcherDiscoveryFinished(LauncherDiscoveryRequest request) { - // We need to support two somewhat incompatible scenarios. - // If there are user extensions present which implement `ExecutionCondition`, and they call config in `evaluateExecutionCondition`, - // they need the TCCL to be right for reading config (that is, the app classloader) - // On the other hand, if the QuarkusTestExtension is registered by a service loader mechanism, it gets loaded after the discovery phase finishes, - // so needs the TCCL to still be the facade classloader. - // This compromise does mean you can't use the service loader mechanism to avoid having to use `@QuarkusTest` and also use Quarkus config in your own test extensions, but that combination is very unlikely. - if (!facadeLoader.isServiceLoaderMechanism()) { - // Do not close the facade loader at this stage, because discovery finished may be called several times within a single run - // Ideally we would reset to what the TCCL was when we started discovery, but we can't, - // because the intercept method will have set something before the discovery start is triggered. - // So, rather annoyingly and clumsily, reset the TCCL to what it was when the first interception happened - Thread.currentThread().setContextClassLoader(origCl); + if (!isProductionModeTests()) { + // We need to support two somewhat incompatible scenarios. + // If there are user extensions present which implement `ExecutionCondition`, and they call config in `evaluateExecutionCondition`, + // they need the TCCL to be right for reading config (that is, the app classloader) + // On the other hand, if the QuarkusTestExtension is registered by a service loader mechanism, it gets loaded after the discovery phase finishes, + // so needs the TCCL to still be the facade classloader. + // This compromise does mean you can't use the service loader mechanism to avoid having to use `@QuarkusTest` and also use Quarkus config in your own test extensions, but that combination is very unlikely. + if (!facadeLoader.isServiceLoaderMechanism()) { + // Do not close the facade loader at this stage, because discovery finished may be called several times within a single run + // Ideally we would reset to what the TCCL was when we started discovery, but we can't, + // because the intercept method will have set something before the discovery start is triggered. + // So, rather annoyingly and clumsily, reset the TCCL to what it was when the first interception happened + Thread.currentThread().setContextClassLoader(origCl); + } } } @Override - public void close() { + public void launcherSessionClosed(LauncherSession session) { try { // Tidy up classloaders we created, but not ones created upstream diff --git a/test-framework/junit5/src/main/resources/META-INF/services/org.junit.platform.launcher.LauncherInterceptor b/test-framework/junit5/src/main/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener similarity index 100% rename from test-framework/junit5/src/main/resources/META-INF/services/org.junit.platform.launcher.LauncherInterceptor rename to test-framework/junit5/src/main/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener