We have some external Libs (lets call them magic.jar) which we have to load within a separate ClassLoader.
(Background: There are different versions of the lib: magic.12.jar, magic.13.jar, ... Different versions contain a lot of same classes which means, we cannot have them in the same classloader.)
The jar-file is located in the resources folder of our project.
Until here, there is no problem. But now the tricky part:
Our project has different build distributions. So the call to get the jar-Resource-URL
URL url = JarExtractor.class.getResource("/lib/magic.jar");
returns different urls:
// if we start from IntelliJ
// -> lib is directly on drive
file:/../workspace/our-application/out/production/resources/lib/magic.jar
// if we build normal artifact
// -> lib is included in our application.jar
jar:file:/tmp/our-application.jar!/BOOT-INF/classes!/lib/magic.jar
// if we build with a wrapping artifact
// -> lib is included in our application.jar which itself is included in a wrapping application
jar:file:/tmp/our-application-wrapped.jar!/BOOT-INF/lib/our-application.jar!/lib/magic.jar
We expected that the URLClassLoader()
would handle also interleaved targets. As we realized that this doesn't work, we built a util which parses the given url and extracts the jar files to a temp folder to which we could have a simple "file:/tmp/..." -URL.
First, our solution feels really dirty. Second is that we cannot expect to always have an accessible file system. So, is there a solution (a lib) or at least a better approach?
Actually we're trying around with an in-memory-URL (inspired by). The idea is to have an URL with its own URLConnection implementation. The approach seemed to be promising but the URLClassLoader just ignores it.