I encountered this confusing issue when working on a larger project, so I’ve created a simple reproduction project to better reproduce and explain my issue. I’m not sure if it is possible for me to upload a zip with the whole structure, but it is only 5 files: https://paste.gg/p/anonymous/f502a8e613a64aeeae671b4c41587c43.
EDIT: The 5 files in my reproduction are also included at the bottom of this question — not just on an external site — as requested. I initially figured it would unnecessarily clutter this page due to the general verbosity of Maven.
I have a parent module MavenTest with 3 submodules: A, B, and C.
A only contains the class org.example.maventest.A
.
B shades A like so:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.example.maventest</pattern>
<shadedPattern>org.example.maventest.a</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
This relocates the org.example.maventest.A
class to org.example.maventest.a.A
.
C shades B like so:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This should simply shade in the relocated org.example.maventest.a.A
class from module B into C’s jar.
Expected behavior: running mvn clean install
to build all the modules should create a jar C that only includes the relocated org.example.maventest.a.A
file.
Actual behavior: When the shade plugin runs for module C, it reports this:
[INFO] --- shade:3.6.0:shade (default) @ C ---
[INFO] Including org.example:B:jar:1.0-SNAPSHOT in the shaded jar.
[INFO] Including org.example:A:jar:1.0-SNAPSHOT in the shaded jar.
[INFO] Dependency-reduced POM written at: /MavenTest/C/dependency-reduced-pom.xml
It seems that module C is inheriting the module A dependency from module B, which causes the original A class to be shaded in as well (using IntelliJ to look inside the jar):
The strange part, is that if I only build module C using mvn clean install -pl :C
, maven correctly only includes the relocated class A:
[INFO] --- shade:3.6.0:shade (default) @ C ---
[INFO] Including org.example:B:jar:1.0-SNAPSHOT in the shaded jar.
[INFO] Dependency-reduced POM written at: /MavenTest/C/dependency-reduced-pom.xml
It seems that in this case, module C is looking at the dependency reduced pom of B produced by the shade plugin where the compile dependency on module A is removed. So, during the full build, I want to reproduce this behavior of C looking at B’s dependency reduced pom.
This also seems to affect compilation. For example, if I add this class to module C:
public class C {
org.example.maventest.A first = null;
org.example.maventest.a.A second = null;
}
When I run the full build (or look at it statically with IntelliJ), this code compiles.
However, when I build module C independently, this code fails because the org.example.maventest.A
class cannot be found. I want the behavior of the independent build, where module A is seemingly excluded from the compile classpath.
Reproduction files
Directory structure:
MavenTest/A/src/main/java/org/example/maventest/A.java
package org.example.maventest;
public class A {
}
MavenTest/A/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>MavenTest</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>A</artifactId>
</project>
MavenTest/B/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>MavenTest</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>B</artifactId>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>A</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.example.maventest</pattern>
<shadedPattern>org.example.maventest.a</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
MavenTest/C/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>MavenTest</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>C</artifactId>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>B</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
MavenTest/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>MavenTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>A</module>
<module>B</module>
<module>C</module>
</modules>
</project>
Output of running Maven
(I tried to include these directly in the question, but StackOverflow complained I exceeded the maximum amount of characters).
mvn clean install
(Full build, incorrect final C jar): https://paste.gg/p/anonymous/ce82a48c1db14a7f9c7c86020b4b79d6
mvn clean install -pl :C -X
(Just module C, correct final jar): https://paste.gg/p/anonymous/dc7c21fcbb6442619a8159d0a0315e0c
4