Thanks for the reply @Chris_Dore!
A simple example is not really possible. This is a plugin I am testing and I see this problem in its TestKit tests. The hibernate-testing-jakarta
project is “virtual” - the plugin takes hibernate-testing
, runs Jakarta’s JakartaTransformer
against it and exposes the transformation as hibernate-testing-jakarta
.
hibernate-testing
is a Java project. hibernate-testing-jakarta
is effectively a Java project though the plugin simply tries to set up everything like the java
or java-library
would have (creates Configurations, POM, etc). It is quite likely that I am just not setting up the metadata (POM) for the hibernate-testing-jakarta
project properly from the plugin
If you can spare some cycles, the plugin is here: GitHub - hibernate/jakarta-transformer-plugin. The ShadowSharedTesting
test deals with this situation. The test project set-up is:
-
real
= the “real” main project
-
real-testing
= test fixtures
-
real-jakarta
= transformed version of real
-
real-testing-jakarta
= transformed version of real-testing
real
depends on real-testing
for test compilation. real-testing
depends on real
for compilation
Both (3) and (4) are virtual projects which are meant to “shadow” (1) and (2) respectively. So the plugin gets applied to (3) and (4) and tries to mimic the (1) and (2) relationship.
- The test
ShadowSharedTesting#jakartaTestingTest
illustrates the problem.
- If you run
ShadowSharedTesting#pomGenerationTest
, you can see the POM generated into the build dir. Again, I am not sure that the POM for the 2 shadow projects are right. But I am also not sure that the POM is what actually gets used when defining a project-dependency.
- You can also run
ShadowSharedTesting#showDependenciesTest
to see the dependency tree that should be applied to test-runtime.
The output from ShadowSharedTesting#showDependenciesTest
is
testRuntimeScope
+--- javax.persistence:javax.persistence-api:2.2 -> jakarta.persistence:jakarta.persistence-api:3.0.0
+--- org.junit.jupiter:junit-jupiter-engine:5.7.0
| +--- org.junit:junit-bom:5.7.0
| | +--- org.junit.jupiter:junit-jupiter-api:5.7.0 (c)
| | +--- org.junit.jupiter:junit-jupiter-engine:5.7.0 (c)
| | +--- org.junit.platform:junit-platform-engine:1.7.0 (c)
| | \--- org.junit.platform:junit-platform-commons:1.7.0 (c)
| +--- org.apiguardian:apiguardian-api:1.1.0
| +--- org.junit.platform:junit-platform-engine:1.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | +--- org.apiguardian:apiguardian-api:1.1.0
| | +--- org.opentest4j:opentest4j:1.2.0
| | \--- org.junit.platform:junit-platform-commons:1.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | \--- org.apiguardian:apiguardian-api:1.1.0
| \--- org.junit.jupiter:junit-jupiter-api:5.7.0
| +--- org.junit:junit-bom:5.7.0 (*)
| +--- org.apiguardian:apiguardian-api:1.1.0
| +--- org.opentest4j:opentest4j:1.2.0
| \--- org.junit.platform:junit-platform-commons:1.7.0 (*)
\--- project :real-testing -> project :real-testing-jakarta
So it would seem that the transitive deps from real-testing-jakarta
are not being used. The classpath applied to Test does not even include real-testing-jakarta
for some reason, even though it is based on this testRuntimeScope
Configuration:
final FileTransformationTask shadowJarTask = ...
testTask.setClasspath(
testRuntimeScope
.plus( targetProject.files( shadowJarTask.getOutput() ) )
.plus( targetProject.files( javaTransformationTask.getOutput() ) )
.plus( targetProject.files( resourcesTransformationTask.getOutput() ) )
);
As shown above, testRuntimeScope
includes real-testing-jakarta
(via substitution). But the testTask’s classpath at runtime is:
############################################################
`:real-jakarta:test` task classpath...
############################################################
-> /tmp/.gradle-test-kit-sebersole/caches/modules-2/files-2.1/jakarta.persistence/jakarta.persistence-api/3.0.0/affc7884a85b6876d438a88b5d21ea29b1cc2dd8/jakarta.persistence-api-3.0.0.jar
-> /tmp/.gradle-test-kit-sebersole/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.7.0/eadb73c5074a4ac71061defd00fc176152a4d12c/junit-platform-engine-1.7.0.jar
-> /tmp/.gradle-test-kit-sebersole/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.7.0/b25f3815c4c1860a73041e733a14a0379d00c4d5/junit-jupiter-api-5.7.0.jar
-> /tmp/.gradle-test-kit-sebersole/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.7.0/84e309fbf21d857aac079a3c1fffd84284e1114d/junit-platform-commons-1.7.0.jar
-> /tmp/.gradle-test-kit-sebersole/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.7.0/d9044d6b45e2232ddd53fa56c15333e43d1749fd/junit-jupiter-engine-5.7.0.jar
-> /tmp/.gradle-test-kit-sebersole/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.0/fc9dff4bb36d627bdc553de77e1f17efd790876c/apiguardian-api-1.1.0.jar
-> /tmp/.gradle-test-kit-sebersole/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.2.0/28c11eb91f9b6d8e200631d46e20a7f407f2a046/opentest4j-1.2.0.jar
-> /home/sebersole/projects/playground/jakarta-transformer-plugin/build/tmp/testKit/testKit803615492/shadowShared/real-jakarta/build/libs/real-jakarta-1.0.0.jar
-> /home/sebersole/projects/playground/jakarta-transformer-plugin/build/tmp/testKit/testKit803615492/shadowShared/real-jakarta/build/classes/java/test
-> /home/sebersole/projects/playground/jakarta-transformer-plugin/build/tmp/testKit/testKit803615492/shadowShared/real-jakarta/build/resources/test
############################################################
Which is verbose, but just shows that the real-testing-jakarta
project is not included. I presume because it is not set up as a project the way dependency resolution needs it to be.
Not sure if it is important, but wanted to point out that in order to handle both java
and java-library
I use compileClasspath
, runtimeClasspath
, testCompileClasspath
and testRuntimeClasspath
as the basis for the deps of the virtual projects (as opposed to directly referring to implementation
, …).