Question

What i am trying to do and have been researching on how to do for many days is to have a mother jar that looks through a folder and loads all the jars in there dynamically ( Not really needing to know about them ) for this to work i need a file inside the plugins called plugin. I Currently have a working class loader that can start the plugins but i can not read the plugin file.

here is my current code:

Load.class

Load(JMenuBar Bar) {

ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
        ClazzL = new URLClassLoader(new URL[]{new File("/home/grant/plugins/MenuPlugin.jar").toURL()}, currentThreadClassLoader);
        Thread.currentThread().setContextClassLoader(ClazzL);

        in = new BufferedReader(new InputStreamReader(ClazzL.getClass().getClassLoader().getResourceAsStream("/menuplugin/plugin")));

        System.out.println("in: " + in.readLine());


        Class c = ClazzL.loadClass("menuplugin.Main");//this works and loads properly
                                                      //it is just that it needs to
                                                      //load from `plugin` using
                                                      //in.readLine();
        API obj = (API) c.newInstance();
        obj.run(Bar);

}

the error is (line 44: in = new Buffered....)

Exception in thread "main" java.lang.NullPointerException
at menuaddon.Load.<init>(Load.java:42)
at menuaddon.Menuaddon.main(Menuaddon.java:39)
Java Result: 1

much help appreciated

the finished working code is:

ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
        ClazzL = new URLClassLoader(new URL[]{new File("/home/grant/plugins/MenuPlugin.jar").toURL()}, currentThreadClassLoader);
        Thread.currentThread().setContextClassLoader(ClazzL);
        in = new BufferedReader(new InputStreamReader(ClazzL.getResourceAsStream("plugin")));
        classpath = in.readLine();
        Class c = ClazzL.loadClass(classpath);
        API obj = (API) c.newInstance();
        obj.run(Bar);
Was it helpful?

Solution

If ClazzL actually is a variable, and references the classloader, then try just

ClazzL.getResourceAsStream("/menuplugin/plugin")

instead. If you do ClazzL.getClass().getClassLoader(), you're trying to load the resource from the classloader of your ClazzL class, not the classloader you have created.

OTHER TIPS

ClazzL.getClass().getClassLoader().getResourceAsStream("/menuplugin/plugin")

That is not loading from the classloader ClazzL, but from the class loader that defines URLClassLoader (i.e. the system classloader).

Try

ClazzL.getResourceAsStream("/menuplugin/plugin")

Get an URL of the plugin file using getResource(), then open an input stream on it.

EDIT: You have to do it using a class that you've loaded using the URL classloader you created - not the classloader's classloader as in your original example - that only sees the classpath of parent classloader, not the one you've just created.

This code should work:

Class c = ClazzL.loadClass("menuplugin.Main");
URL pluginFileUrl = c.getResource("/menuplugin/plugin"); // This returns an URL representing resource on the classpath with a given file name.
InputStream inputStream = pluginFileUrl.openStream();

EDIT 2: NilsH's answer is of course a much more elegant shortcut.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top