alek
alek

Reputation: 151

Load a class to Java classpath dynamically using Eclipse and OSGi

Combining the information from many posts on this site and many others, I got the following code to dynamically add (at run time) a directory containing classes to the classpath and load a class within that directory.

I'm using OSGi bundles and running from eclipse an "Eclipse Application" (a kind of Run Configuration).

This is the code I'm using:

CASE 1: (both cases are different things I've tried to do the same thing.)

File file = new File("/Users/alek/fastFIX/myJPass/"); 
URL url = file.toURI().toURL(); 
URL[] urls = new URL[]{url}; 
ClassLoader cl = new URLClassLoader(urls); 
Class  cls = cl.loadClass("GuiLauncher");    //the file GuiLauncher.class is in the /Users/alek/fastFIX/myJPass/ directory
Class[] argTypes = new Class[] { String[].class };
Method main = cls.getDeclaredMethod("main", argTypes); //trying to run the main class
main.invoke(null, (Object) args);

I don't get any error, and nothing happens. I've also tryied the following, as I actually need the loaded class to interact with other (already loaded) classes.

CASE 2:

ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] {  new File("/Users/alek/fastFIX/myJPass/").toURL() }, currentThreadClassLoader);
Thread.currentThread().setContextClassLoader(urlClassLoader);

then i load like this:

 Class<?> c = Class.forName("GuiLauncher");

or like this:

Class<?> c = Thread.currentThread().getContextClassLoader().loadClass("GuiLauncher");

and try to invoke the main function like this:

Class[] argTypes = new Class[] { String[].class };
Method main = cls.getDeclaredMethod("main", argTypes); //trying to run the main class
main.invoke(null, (Object) args);

here also nothing happens.

Any clue of what could be happening? I've read all related posts here and many places else with no luck.

Upvotes: 2

Views: 2872

Answers (2)

Burkhard Losch
Burkhard Losch

Reputation: 39

In OSGI framework it is necessary to add the OSGI class loader as a parent, something like this: ... ClassLoader cl = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader()); ...

Upvotes: 1

DNA
DNA

Reputation: 42617

In case 1, I suspect that the GuiLauncher class is already on the classpath, so may get loaded by the default classloader. Try doing Class.forName() before setting up the dynamic classloader, to confirm that there's no class available. If you are in Eclipse, you need to be careful that the class is not included on the Eclipse classpath, which is what would normally happen. You might need to compile it once then move the .java and .class files elsewhere to hide them from Eclipse!

In case 2:

Class.forName("GuiLauncher");

will not work as you expect, because this will use the system classloader. This should fail, hence my suspicion above. You need use the other version of this method that specifies your dynamic classloader:

Class.forName("GuiLauncher", true, urlClassLoader)

The following code works for me.

import java.net.*;
import java.lang.reflect.*;
import java.io.File;

public class Main{

public static void main(String[] args)
{
    try{
      Class  cls = Class.forName("Plugin");
    }
    catch(Exception e){
      System.out.println("Nothing there!");
    }

    try{
      File file = new File("plugin"); 
      ClassLoader cl = new URLClassLoader(new URL[]{file.toURI().toURL()}); 
      Class  cls = Class.forName("Plugin", true, cl);
      Method main = cls.getDeclaredMethod("main", new Class[] { String[].class });
      main.invoke(null, (Object) args);
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }
}

The Plugin class is compiled in the plugin subfolder, so it's not on the classpath used to run Main, as shown by the first Class.forName().

public class Plugin{
  public static void main(String[] args)
  {
    System.out.println("Plugin was invoked!");
  }
}

and prints out:

Nothing there! 
Plugin was invoked!

Upvotes: 0

Related Questions