Skip to content

Avoid Adding Duplicated JUnit Entries on Classpath #712

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dnestoro
Copy link
Collaborator

@dnestoro dnestoro commented Apr 2, 2025

Fix for: #305

Solution:

  • Collect all junit dependencies (their modules) that are already on classpath
  • Add those modules to the modules set (here)
  • This set will be later used for filtering dependencies that we want to add on classpath (here)

When running java-application-with-tests with mvn -Pnative package I am getting following results:

  • Without this change:

[INFO] Executing: /.sdkman/candidates/java/21.0.4-graal/bin/native-image -cp /native-build-tools/samples/java-application-with-tests/target/classes:/native-build-tools/samples/java-application-with-tests/target/test-classes:/.m2/repository/org/junit/jupiter/junit-jupiter/5.10.0/junit-jupiter-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.10.0/junit-jupiter-api-5.10.0.jar:/.m2/repository/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/.m2/repository/org/junit/platform/junit-platform-commons/1.10.0/junit-platform-commons-1.10.0.jar:/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.10.0/junit-jupiter-params-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.10.0/junit-jupiter-engine-5.10.0.jar:/.m2/repository/org/junit/platform/junit-platform-engine/1.10.0/junit-platform-engine-1.10.0.jar:/.m2/repository/org/graalvm/buildtools/native-maven-plugin/0.10.7-SNAPSHOT/native-maven-plugin-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/utils/0.10.7-SNAPSHOT/utils-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/graalvm-reachability-metadata/0.10.7-SNAPSHOT/graalvm-reachability-metadata-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/junit-platform-native/0.10.7-SNAPSHOT/junit-platform-native-0.10.7-SNAPSHOT.jar:/.m2/repository/org/junit/platform/junit-platform-console/1.10.0/junit-platform-console-1.10.0.jar:/.m2/repository/org/junit/platform/junit-platform-reporting/1.10.0/junit-platform-reporting-1.10.0.jar:/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/.m2/repository/org/junit/platform/junit-platform-launcher/1.10.0/junit-platform-launcher-1.10.0.jar:/.m2/repository/org/junit/platform/junit-platform-engine/1.10.0/junit-platform-engine-1.10.0.jar:/.m2/repository/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/.m2/repository/org/junit/platform/junit-platform-commons/1.10.0/junit-platform-commons-1.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter/5.10.0/junit-jupiter-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.10.0/junit-jupiter-api-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.10.0/junit-jupiter-params-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.10.0/junit-jupiter-engine-5.10.0.jar --no-fallback --verbose -o /native-build-tools/samples/java-application-with-tests/target/native-tests -Djunit.platform.listeners.uid.tracking.output.dir=/native-build-tools/samples/java-application-with-tests/target/test-ids --features=org.graalvm.junit.platform.JUnitPlatformFeature org.graalvm.junit.platform.NativeImageJUnitLauncher

  • With this change:

[INFO] Executing: /.sdkman/candidates/java/21.0.4-graal/bin/native-image -cp /native-build-tools/samples/java-application-with-tests/target/classes:/native-build-tools/samples/java-application-with-tests/target/test-classes:/.m2/repository/org/junit/jupiter/junit-jupiter/5.10.0/junit-jupiter-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.10.0/junit-jupiter-api-5.10.0.jar:/.m2/repository/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/.m2/repository/org/junit/platform/junit-platform-commons/1.10.0/junit-platform-commons-1.10.0.jar:/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.10.0/junit-jupiter-params-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.10.0/junit-jupiter-engine-5.10.0.jar:/.m2/repository/org/junit/platform/junit-platform-engine/1.10.0/junit-platform-engine-1.10.0.jar:/.m2/repository/org/graalvm/buildtools/native-maven-plugin/0.10.7-SNAPSHOT/native-maven-plugin-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/utils/0.10.7-SNAPSHOT/utils-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/graalvm-reachability-metadata/0.10.7-SNAPSHOT/graalvm-reachability-metadata-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/junit-platform-native/0.10.7-SNAPSHOT/junit-platform-native-0.10.7-SNAPSHOT.jar:/.m2/repository/org/junit/platform/junit-platform-console/1.10.0/junit-platform-console-1.10.0.jar:/.m2/repository/org/junit/platform/junit-platform-reporting/1.10.0/junit-platform-reporting-1.10.0.jar:/.m2/repository/org/junit/platform/junit-platform-launcher/1.10.0/junit-platform-launcher-1.10.0.jar --no-fallback --verbose -o /native-build-tools/samples/java-application-with-tests/target/native-tests -Djunit.platform.listeners.uid.tracking.output.dir=/native-build-tools/samples/java-application-with-tests/target/test-ids --features=org.graalvm.junit.platform.JUnitPlatformFeature org.graalvm.junit.platform.NativeImageJUnitLauncher

  • When I update junitPlatform and junitJupiter versions in the project to 1.11.0 and 5.11.0 :

[INFO] Executing: /.sdkman/candidates/java/21.0.4-graal/bin/native-image -cp /native-build-tools/samples/java-application-with-tests/target/classes:/native-build-tools/samples/java-application-with-tests/target/test-classes:/.m2/repository/org/junit/jupiter/junit-jupiter/5.10.0/junit-jupiter-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.10.0/junit-jupiter-api-5.10.0.jar:/.m2/repository/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/.m2/repository/org/junit/platform/junit-platform-commons/1.10.0/junit-platform-commons-1.10.0.jar:/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.10.0/junit-jupiter-params-5.10.0.jar:/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.10.0/junit-jupiter-engine-5.10.0.jar:/.m2/repository/org/junit/platform/junit-platform-engine/1.10.0/junit-platform-engine-1.10.0.jar:/.m2/repository/org/graalvm/buildtools/native-maven-plugin/0.10.7-SNAPSHOT/native-maven-plugin-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/utils/0.10.7-SNAPSHOT/utils-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/graalvm-reachability-metadata/0.10.7-SNAPSHOT/graalvm-reachability-metadata-0.10.7-SNAPSHOT.jar:/.m2/repository/org/graalvm/buildtools/junit-platform-native/0.10.7-SNAPSHOT/junit-platform-native-0.10.7-SNAPSHOT.jar:/.m2/repository/org/junit/platform/junit-platform-console/1.11.0/junit-platform-console-1.11.0.jar:/.m2/repository/org/junit/platform/junit-platform-reporting/1.11.0/junit-platform-reporting-1.11.0.jar:/.m2/repository/org/junit/platform/junit-platform-launcher/1.11.0/junit-platform-launcher-1.11.0.jar --no-fallback --verbose -o /native-build-tools/samples/java-application-with-tests/target/native-tests -Djunit.platform.listeners.uid.tracking.output.dir=/native-build-tools/samples/java-application-with-tests/target/test-ids --features=org.graalvm.junit.platform.JUnitPlatformFeature org.graalvm.junit.platform.NativeImageJUnitLauncher

From the output we see that there are no 5.11.0 entries because this sample sets its own JUnit version through gradle.properties file. With this fix we are giving the advantage to the user's declared version (illustrated in the example above).

Possible problem: If we update hardcoded JUnit version to 5.11.0 here (for example to support @FieldSource annotation - like I did in this PR) and user declared earlier JUnit version in its project (for example 5.10.0) we won't have 5.11.0 artifact on the classpath, and therefore we will get NoClassDefFoundError since FieldSource is not available before 5.11.0 version.
In that case we can catch and ignore NoClassDefFoundError when supporting annotations from newer JUnit versions. The question is: can this harm existing projects if we suddenly remove "duplicates" (same artifacts but with different versions)? Are we currently relying on some JUnit features that are only available from JUnit 5.10.0? cc @melix @sbrannen

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Apr 2, 2025
@dnestoro dnestoro force-pushed the dnestoro/fix-duplicated-junit-classpath-entries branch from 7cd95e7 to c9c3544 Compare April 7, 2025 08:43
@dnestoro dnestoro force-pushed the dnestoro/fix-duplicated-junit-classpath-entries branch from 90d0b96 to 095a84d Compare April 10, 2025 13:56
@dnestoro dnestoro self-assigned this Apr 11, 2025
@dnestoro dnestoro requested review from melix and olpaw April 11, 2025 09:06
@melix
Copy link
Collaborator

melix commented Apr 11, 2025

I am a bit confused by this issue. IMO, the version of JUnit declared by users should take precedence. This means that whatever JUnit version we need should only be needed at compile time of native build tools, not runtime. So it's probably a dependency scope mistake (implementation instead of compileOnly). We shouldn't rely on dirty tricks to remove jars by hand from classpath.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants