Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Jar Combining several jars into one executable Jar

I am aware that to combine several jars and create one executable jar, I would need to use a tool like OneJar if I don't want to unpack the dependent jars. OneJar has its own custom class loader which can find the required classes in the associated jars and load them.

My question is : Why is the default class loader not able to load classes from within the attached jars. Is it because of Security ? I would appreciate a clear explanation of the reasons behind the need for a custom class loader when creating a single executable jar which holds other dependent jars (without unpacking them). Thanks,

like image 612
Macky Avatar asked Jan 25 '26 00:01

Macky


2 Answers

The technical reason is that the uri specification for jar: does not support nesting.

You could write a URI handler that addresses this need, but performance will start to hit as you nest down inside each jar file.

With a single jar file, random access is possible as the index gives file system offsets and you can seek each offset and read only the file you want

With a nested jar, you can seek the inner jar, but to pull a file out of that jar you have to unzip the inner jar from the outer before you can seek.

I would look at solutions such as those offered by either OSGi or by the Maven Shade Plugin if you don't want to extract the jar files to a temporary directory and build your own classloader from the resulting classpath

like image 144
Stephen Connolly Avatar answered Jan 26 '26 13:01

Stephen Connolly


In addition to other answers (the one from Stephen being the more accurate so far), also consider that the JVM does not preemptively explore the available classpath entries, so in order to find class com.foo.Bar it will look at a path like com/foo/Bar.class in the entries listed in the classpath. If this path could be inside a nested jar (that is not itself listed in the classpath declaration), in order to find said path the classloader should first explore all the nested jar (unpacking them in the process) in order to do the appropriate lookup.

like image 32
Grim Avatar answered Jan 26 '26 14:01

Grim