javaurlclassloader

User URLClassLoader to load jar file "on the fly"


Ok, basically, I try to use the method described here JarFileLoader to load a jar containing a class that will be used the same as if it was on the classpath (the class name will be dynamic so that we can just add any jar with any class and the program will load it through parsing a text file, in the main line).

Problem is that when I debug and check the URLClassLoader object

protected Class<?> findClass(final String name)

Line :

Resource res = ucp.getResource(path, false);

the getResource() does not find the class name in parameter.

Does someone already try loading a jar file this way ?

Thanks.

Loader :

public class JarFileLoader extends URLClassLoader {
    public JarFileLoader() {
        super(new URL[] {});
    }

    public JarFileLoader withFile(String jarFile) {
        return withFile(new File(jarFile));
    }

    public JarFileLoader withFile(File jarFile) {
        try {
            if (jarFile.exists())
                addURL(new URL("file://" + jarFile.getAbsolutePath() + "!/"));
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException(e);
        }
        return this;
    }

    public JarFileLoader withLibDir(String path) {
        Stream.of(new File(path).listFiles(f -> f.getName().endsWith(".jar"))).forEach(this::withFile);
        return this;
    }
}

Main :

public static void main(String[] args) {
    new Initializer();
    JarFileLoader cl = new JarFileLoader();
    cl = cl.withFile(new File("libs/dpr-common.jar"));
    try {
        cl.loadClass("com.*****.atm.dpr.common.util.DPRConfigurationLoader");
        System.out.println("Success!");
    } catch (ClassNotFoundException e) {
        System.out.println("Failed.");
        e.printStackTrace();
    } finally {
        try {
            cl.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Here the test class I used. When I debug URLClassLoader I can see in the third loop the path of the jar file(loop on the classpath and the URL you add here), but still does not find ressource (and cannot debug the class URLClassPath so do not know what getRessource does exactly).


Solution

  • Ok I take the answer from this question : How to load all the jars from a directory dynamically?

    And changing the URL part at the beginning with the way it is done in the long part it works.

    So an example could be :

    String path = "libs/dpr-common.jar";
    if (new File(path).exists()) {
        URL myJarFile = new File(path).toURI().toURL();
        URL[] urls = { myJarFile };
        URLClassLoader child = new URLClassLoader(urls);
        Class DPRConfLoad = Class.forName("com.thales.atm.dpr.common.util.DPRConfigurationLoader", true, child);
        Method method = DPRConfLoad.getDeclaredMethod("getInstance");
        final Object dprConf = method.invoke(DPRConfLoad);
    }
    

    All my time wasted in search while it was the example which was wrong... Still does not understand why they use a stupid URL like "jar:file..." etc.

    Thanks everyone.