maven-shade-plugin
maven-shade-plugin copied to clipboard
[MSHADE-402] Shading produces empty test jar
Cédric Champeau opened MSHADE-402 and commented
Dear maintainers,
I'm working with the shade plugin in the context of a workaround for a Windows bug: when invoking a CLI in Windows, there's a maximum length that you can use. The GraalVM native-image is invoked on CLI with a "classpath" argument which easily exceeds that limit. There are several options to workaround this but in this context, the most promising, which worked for the Gradle plugin, was to use shading.
For the main artifact, this technique works properly: we can use the "shade" plugin to generate a shaded jar which is then passed to native-image. However, we also have support for unit test execution "as a native image", which means that we need to build a native image which includes test classes and the test runtime (e.g JUnit Platform).
Unfortunately, this technique doesn't work for Maven. First of all, let's see how the build is configured:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadeTestJar>true</shadeTestJar>
</configuration>
</plugin>
As you can see, I'm using shadeTestJar, but if you run the package phase, you will see that the resulting jar is empty. After trying to figure out why, it turns out there are 2 different reasons:
- the first one seems to be that you must generate a test jar before hand. This isn't mentioned in the docs, but I could get a non empty jar by adding this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
- the second problem is that the shaded generated test jar doesn't include the test dependencies
After debugging, I noticed that the project.getDependencies() method did not return the test dependencies. The javadocs for this method state that they should include the test dependencies, since when this code is executed, the "test" phase has been executed. Debugging showed me that the "resolved dependencies" cache was correct, but that a filter only kept the "runtime" dependencies. The mojo descriptor mentions:
@Mojo( name = "shade", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true, requiresDependencyResolution = ResolutionScope.RUNTIME )
So I guess the problem comes from the "requiresDependencyResolution" value, which should be set to "TEST" for the test jar to include test dependencies.
However, I suspect that by changing this parameter to TEST, then the main jar would suddenly start including test dependencies, which isn't expected.
Let me know if my analysis is correct. I'm open to suggestions on how to workaround this problem.
Thanks!
Affects: 3.2.4