The term "JAR file" can mean at least two things, or rather, has at least two facets of their meaning. This basically means the container format: basically, a ZIP file with the META-INF directory. In more detail, this means that this container is used as a way to batch class files.
In the sense of having a container, there is no intent regarding the contents; the file may contain class files, other JARs (in any sense!), etc. But in the sense that I am a package of code, I believe that the goal for JAR files is not to contain any dependencies.
If you read the JAR File Specification , you will find that there are several allusions to storing class files, but nothing about storing other JAR files. Accordingly, if you look at the implementation of the JAR file class loader in the JRE, it will not be able to do anything useful in nested JAR files.
In addition, the JAR specification describes in detail how to work with non-nested dependencies: the Class-Path attribute . This allows the JAR file to link to other JAR files in the file system.
Now in JAR files in JA format, files are not the only use of JAR files in-sense-of-a-container. WAR, EAR and RAR (and much more) are all JAR files used for specific purposes. Each of them can contain other JARs: WARs can contain JAR files in JS-format, and EARs can contain those as well as WAR. However, these are completely different animals than JAR files in their class. It is worth noting that their use requires special class loaders that are not part of the standard Java library.
The way WARs, etc. can collect many JAR files together, it is really very useful, and this is a real shame that does not have a common mechanism for doing this in Java outside of Java EE. It would be great to have an “application archive” or “meta archive” that simply bundled some JARs.
So, you still have the problem of users who need 25 JARs to use your plugin. You have about two options.
First, you accept the pain and distribute your plugin as a ZIP full of JARs that users will need to unzip.
Secondly, you join the 21st century and use a build tool and distribution mechanism that automatically handles dependencies: in practice, this means using Gradle or Maven or some other tool (like Ant) with Ivy to get dependencies on Maven Central, and then release your code along with the POM file that lists these dependencies. Users can then load your JAR and your POM and have their own build tool to get the dependencies.
If you are on the second route, it might be wise to also release zip dependencies, in the interests of users who do not use automatic dependency management.