Saturday, July 25, 2015
How to package a jar-with-dependencies with maven and how to manage resource collisions (if we have multiple log4j.xml for example).
Sometimes it's easier to distribute our application in a single fat jar (myapp-1.0-jar-with-dependencies.jar) instead of distributing our jar + libs.jar. To achieve this, we can use maven-assembly-plugin and the jar-with-dependencies descriptor.
However, the jar-with-dependencies works but until we have resource collisions. Imagine that you have your own /src/main/resources/log4.xml but one of your dependencies (i.e. dependency.jar) has a /log4j.xml as well.
To handle this situation, we can redefine the jar-with-dependencies assembly descriptor so we start packing the fat jar first with our own project files and then include the rest of the dependencies. That will work because maven will not overwrite files that already exists.
Another thing to keep in mind, is that it works fine for any resource, except for the MANIFEST.MF file that is handled by the maven archiver-plugin. In that case, we must redefine the manifest configuration in the maven-assembly-plugin.
Here is the configuration you need to package your own myapp-1.0.0-jar-with-dependencies.jar with your own log4j and MANIFEST and not die trying:
And here is the src/main/assembly/jar-with-dependencies:xml: