I would like to combine several jars into an Uberjar.
In Java I know how to shade dependencies using these two tools:
- https://maven.apache.org/plugins/maven-shade-plugin/
- https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow
But I have a web service that needs to take a dynamic classpath and create an uberjar from it. But being that it is literally a backend server, Maven and Gradle are not tools available for use.
As you can see from the source code of these plugins, it's not just as easy as build a combined zip file with all their contents. You have to do some resolution on duplicate resources, and some special log4j cache configuration as well.
Is there a Java library that is capable of creating the same thing John Rengelman's shadow tool does, but without actually running from Maven/Gradle?
Actually this turns out to be easy enough to do.
You create a
ZipArchiveOutputStreamand iterate through each jar file. You "apply" each jar to the output stream as you go.But - you must make sure to exclude these files:
This works, but results in this issue with logging: log4j2 ERROR StatusLogger Unrecognized conversion specifier
Then you have to properly handle Log4j2 plugin cache files as this class does:
https://github.com/edwgiz/maven-shaded-log4j-transformer/blob/master/src/main/java/io/github/edwgiz/log4j/maven/plugins/shade/transformer/Log4j2PluginCacheFileTransformer.java
This is now working for me.