0

I have this maven multi-module project :

ModuleA src pom.xml target ModuleA-with-dependencies-shaded.jar (version 4.1 of lucene relocated) ModuleB src pom.xml target ModuleB-with-dependencies.jar (version 7.5.0 of lucene) ModuleDist assembly all.xml pom.xml (shaded plugin for jar + assembly for Docker) 

The dist pom plugins are configured like this :

 <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <shadedClassifierName>all</shadedClassifierName> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <!--remove models from jar see mitie --> <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer"> <resource>.dat</resource> </transformer> </transformers> <artifactSet> <excludes> <exclude>log4j:log4j:jar:</exclude> </excludes> </artifactSet> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <phase>package</phase> <id>make-dist</id> <goals> <goal>single</goal> </goals> <configuration> <descriptors> <descriptor>src/assembly/all.xml</descriptor> </descriptors> </configuration> </execution> </executions> </plugin> 

And the assembly all.xml :

<assembly> <id>all</id> <formats> <format>dir</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <fileSets> <fileSet> <directory>${project.basedir}/src/main/docker</directory> <outputDirectory>/</outputDirectory> <includes> <include>*</include> </includes> </fileSet> <fileSet> <directory>${project.build.directory}</directory> <outputDirectory>lib</outputDirectory> <includes> <include>*.jar</include> </includes> </fileSet> </fileSets> </assembly> 

As the ModuleA is having a transitive dependency on lucene 4.1 (but relocated so it won't clash with moduleB) and ModuleB is having a transitive dependency on lucene 7.5.0, I'd like to use the previously built and shaded jar of ModuleA in the maven shaded plugin of ModuleDist (because if I relocate lucene in ModuleDist it is relocating all lucene classes).

How could I do that ?
or is there another way of doing this ?

2
  • 1
    The shaded jar can be addressed by the same coordinates as the module it is done but you have to add <classifier>shaded</classifier> ... Commented Mar 4, 2020 at 18:38
  • thank you @khmarbaise, we used another classifier name but that's what we did. Commented Mar 5, 2020 at 16:04

1 Answer 1

1

To add all your jars of the runtime dependencies to the assembly, add something like this:

<?xml version="1.0"?> <assembly> ... <dependencySets> <dependencySet> <outputDirectory>/lib</outputDirectory> <unpack>false</unpack> <scope>runtime</scope> </dependencySet> </dependencySets> </assembly> 

Take a look at the assembly plugin documentation for more details. A working example can be found here (no shading used).

My personal experience is that it's better to only have one final module that assembles all stuff. This way the shader doesn't have to disassemble and assembler everything over and over.

Shading is a big problem when using Jackson and Log4j2 because it breaks some extension lookup mechanisms that expect everything to be in a separate jar. I recommend not using it anymore.

Sign up to request clarification or add additional context in comments.

5 Comments

Yeah but then you'll end with several jars that may be loaded in different order, and the result will be different function of the order. I wanted to end with a fixed jar
It's up to your preference: The loading order is defined by the classpath. If you have a shaded jar, possible collisions will be 'resolved' by the shader (=usually not resolved). Is the dependencySets-part working for you?
yes we used dependency set before making the docker image build. But as we had to remove NLP models and to have a jar ready before the docker assembly we've chosen to use the shade plugin that broke the final jar. We ended up with 2 assemblies, and chaining them for the final docker folder.
Good :)! If this solved your problem, It would be nice if you marked the question as resolved.
it's not to make the assembly that solved the issue (as i told you we were doing this before having to build the docker assembly) it's the idea to make two assemblies with the second taking the deliverables of the previous one. I voted up your answer but I will explicit what we did in another post

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.