0

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).

CodeKiller
  • 67
  • 1
  • 7
  • Tried this one too : [JarFileLoader](https://gist.github.com/culmat/e950fd34a2a2c6d8f906c312dd39bf62) Does not change anything. – CodeKiller Sep 03 '18 at 09:12
  • You're going to have to supply more details of your code if you want us to help you debug it. Ideally supply a repro in the form of a Java main program or JUnit test. It will have dependencies, but you can explain those. – Michael Kay Sep 03 '18 at 09:50
  • It is unclear if loading classes from Jar files works or not or if only loading resources from the Jar file leads to issues. Maybe you are just having a [path issue](https://stackoverflow.com/questions/13269556/strange-behavior-of-class-getresource-and-classloader-getresource-in-executa) while loading resources – Roman Vottner Sep 03 '18 at 09:54
  • I just find a post about that I will try now. If it work I will close this question. :-) https://stackoverflow.com/questions/21904219/how-to-load-all-the-jars-from-a-directory-dynamically?rq=1 – CodeKiller Sep 03 '18 at 14:37
  • Ok the easy way is wrong but after correction it finally works ! I do'nt know why examples are wrong while the long way explained with the loop and so on is right... So the only thing to do is to use the internal method toURL on the file that's all... `String path = "libs/dpr-common.jar"; if (new File(path).exists()) URL myJarFile = new File(path).toURI().toURL();` – CodeKiller Sep 03 '18 at 15:15

1 Answers1

0

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.

CodeKiller
  • 67
  • 1
  • 7