AntoineB
AntoineB

Reputation: 4694

How to load a JAR stored inside your application resources in a URLClassLoader

I'm trying to load a JAR file in a URLClassLoader. This JAR file is stored in the resources of my project, and its working fine with the following code when I'm running my project using maven:

new URLClassLoader(
    new URL[]{MyClass.class.getClassLoader().getResource("dependencies/dependency.jar")},
    ClassLoader.getSystemClassLoader().getParent()
);

However, when I build the project using mvn clean install and I then try to run the generate JAR using java -jar myapp.jar it seems like the dependency.jar is not loaded. The dependency.jar file is properly stored inside the project JAR under dependencies/dependency.jar, but it's not read.

I assume that it cannot be loaded from inside a JAR file, but is their a workaround?

I think a solution would be to use getResourceAsStream, but I would then need to transform this stream into a URL.

If possible I'd like to use a solution that wouldn't involve a temporary file created to store the content of dependency.jar.

Upvotes: 2

Views: 322

Answers (1)

Nicolas Filotto
Nicolas Filotto

Reputation: 44965

I believe that your problem is due to the fact that it cannot read a zip in zip, so you should copy your jar file into a temporary file and provide this temporary file to your URLClassLoader as next:

// Get the URL of my jar file
URL url = MyClass.class.getResource("/dependencies/dependency.jar");
// Create my temporary file
Path path = Files.createTempFile("dependency", "jar");
// Delete the file on exit
path.toFile().deleteOnExit();
// Copy the content of my jar into the temporary file
try (InputStream is = url.openStream()) {
    Files.copy(is, path, StandardCopyOption.REPLACE_EXISTING);
}
// Create my CL with this new URL
URLClassLoader myCL = new URLClassLoader(
    new URL[]{path.toUri().toURL()}, ClassLoader.getSystemClassLoader().getParent()
);

Upvotes: 1

Related Questions