I'm building a client server application. During runtime the client application loads a jar file from the server application and stores it. I run both the client and the server application as jar files. I now want to load the class contained in this downloaded jar file.
For example I have an interface A and a class B implementing A. The client application does not know about the class B, its name or even its existence. After the start of the client application the client applications downloads a jar file containing a jar file with content: server/package/B.class where server and package are folders.
Now the client Application should load this class B from the downloaded jar file with the following code:
URL downloadURL = downloadFolder.toURI().toURL();
URL[] downloadURLs = new URL[] { ruleSetFolderURL };
URLClassLoader loader =
new URLClassLoader(downloadURLs);
Class tmp = loadClass(server.package.B);
But then I get a ClassNotFoundException
in the last line. Do I first have to extract the jar file? the folder structure in the jar file is like the folder structure in the bin directory of the server application.
To load a class dynamically from a jar file that implements a certain interface, but you do not know in advance which class that will be and the jar file itself does not specify any default "plugin" class, you can iterate through the downloaded jar and get a list of classes contained in the jar like this:
once the classes are known which are included in the jar file, you need to load each class and check if they implement the desired interface like this:
as you can now collect all implementations of a certain interface you can simple initialize a new instance via
Note that this example assumes that A is an interface. If no implementing class could be found within the Jar-File the jar file will be loaded by the classloader but no instantiation of an object will happen.
Note further that it is always good practice to provide a parent classloader - especially with URLClassLoader. Else it might happen that certain classes which are not contained in the Jar-File might be missing and therefore you will get a
ClassNotFoundException
on trying to access them. This is due to the delegation mechanism used by classloaders which first ask their parent if they know the class definition for the required class. If so, the class will be loaded by the parent; if not, the class will be loaded by the created URLClassLoader instead.Keep in mind that loading the same class multiple times with different ClassLoaders is possible (peer-classloaders). But although the Name and bytes of the class might be the same, the classes are not compatible as different classloader instances are used - so trying to cast an instance loaded by classloder A to a type loaded by classloader B will fail.
@Edit: modified the code to avoid null values from being returned, instead more-or-less appropriate exceptions are thrown. @Edit2: as I am not able to accept code review suggestions I edited the review directly into the post