3

I have a program which needs to be able to dynamically load JARs at runtime - after looking around I beleive this uses URLClassLoader, but I'm not sure how to get it to work. The JAR "openup.jar" is in the same directory as the program.

Ideally I would like to be able to load this JAR without having to specify each individual class inside it.

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
Myn
  • 691
  • 4
  • 9
  • 19
  • 3
    possible duplicate of [How should I load Jars dynamically at runtime?](http://stackoverflow.com/questions/60764/how-should-i-load-jars-dynamically-at-runtime) – dogbane Jan 11 '11 at 11:13
  • What exactly do you mean by "load this JAR without having to know what is inside it."? What exactly do you want to load from it, then? – Joachim Sauer Jan 11 '11 at 11:29
  • Why would you want to load a jar without knowing what is inside it ? Do you want to handle it as a zip file or are you interested in loading java classes ? – pgras Jan 11 '11 at 11:30
  • Apologies, that was poorly phrased - what I mean is, is it possible to load the JAR without having to specify the individual classes to be used. There are a good 100+ classes (all of which I need to use) within each of the JARs I'm using - what I meant was is it possible to load them without using getClass() for each class in each JAR? – Myn Jan 11 '11 at 11:42
  • Where *do* you use those classes? In Java classes aren't "loaded" through unknown magic. They are loaded because they are referenced somewhere. What *exactly* references the classes that you want to have loaded from that jar? The "clean" solution is to create a classloader that is able to load the jar in question and have the classes that *depend on that jar* be loaded from a classloader that has set the jar classloader as its parent. – Joachim Sauer Jan 11 '11 at 11:49
  • I'm afraid I'm not sure what you mean there but I'm going to take the answer that it is not possible to do what I'm trying to. I beleive I'll have to go through the painstaking task of individually referencing each class I need to use. Thanks for the input everyone. – Myn Jan 11 '11 at 12:09

2 Answers2

1

What I successfully used:

@SuppressWarnings("unchecked")
public void addURL(URL u) throws IOException {
    URLClassLoader sysLoader = (URLClassLoader) ThisClass.class.getClassLoader();
    URL urls[] = sysLoader.getURLs();
    for (int i = 0; i < urls.length; i++) {
        if (urls[i].toString().equalsIgnoreCase(u.toString())) {
            return;
        }
    }
    Class sysclass = URLClassLoader.class;
    try {
        Method method = sysclass.getDeclaredMethod("addURL", parameters);
        method.setAccessible(true);
        method.invoke(sysLoader, new Object[] { u });
    } catch (Throwable t) {
        throw new IOException("Error, could not add URL to system classloader");
    }
}

An almost identical solution is indeed presented in How should I load Jars dynamically at runtime?

Community
  • 1
  • 1
morja
  • 8,297
  • 2
  • 39
  • 59
  • 1
    That looks like a terrible idea, since it makes a lot of assumptions that are in no way guaranteed: 1.) that the classloader of `ThisClass` is an `URLClassLoader`; 2.) that the `URLClassLoader` class has a `addURL` method (that does what you want) and 3.) that you may invoke `setAccessible()` (i.e. no security manager is running and prohibiting that). – Joachim Sauer Jan 11 '11 at 11:29
  • 1
    Yes, that is true, but it works well in my case. Do you have a cleaner solution? – morja Jan 11 '11 at 11:31
  • Thanks Morja, I *think*, if I understand the code correctly, this might do what I was after but if not then it was still an answer, so thank you. – Myn Jan 11 '11 at 12:11
0

Here I am explaining the full process of creating a jar and then loading a jar dynamically in another project:

Steps to create jar:

  1. Create a new Project in any IDE(Eclipse).
  2. Add a Sample class in packages(in my case MyClass).
  3. Do right-click on the project and then export as jar and give a local path of system location where the jar wants to keep(right-click -> Export -> choose java/jar file -> next ->give path -> finish).
  4. Then jar will be available at given location.

package newJar.com.example;

public class MyClass {

public MyClass() {
    // TODO Auto-generated constructor stub
}

public void helloWorld() {
    System.out.println("Hello from the helloWorld");
}

}

Steps to load the jar dynamically:

  1. Create a new project and add below code:

    public class CustomClass {

    public CustomClass() { // TODO Auto-generated constructor stub }

    public void getCall(File myJar) {

     try {
    
         URLClassLoader loader = new URLClassLoader(new URL[] { myJar.toURI().toURL() },
                 CustomClass.class.getClass().getClassLoader());
    
         Class classToLoad = Class.forName("newJar.com.example.MyClass", true, loader);
         System.out.println(classToLoad);
         Method method = classToLoad.getDeclaredMethod("helloWorld");
         Object instance = classToLoad.newInstance();
         Object result = method.invoke(instance);
    
     } catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | SecurityException
             | InstantiationException | IllegalAccessException | IllegalArgumentException
             | InvocationTargetException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
     }
    

    }

    public static void main(String[] args) { // TODO Auto-generated method stub

     File myJar = new File("Path of your jar ");//"D:\\ECLIPSE\\myjar.jar"
     CustomClass cls = new CustomClass();
     cls.getCall(myJar);
    

    }

}

This is how it can make use of the jar and if the jar is on the server then can give the server path instead of the local path.