使用Eclipse和OSGi动态地将类加载到Java类路径

时间:2012-10-03 18:13:17

标签: java eclipse dynamic osgi classpath

结合本网站和许多其他帖子上的许多帖子的信息,我得到以下代码,以动态添加(在运行时)包含类到classpath的类的目录,并在该目录中加载一个类。

我正在使用OSGi包并从eclipse运行“Eclipse Application”(一种运行配置)。

这是我正在使用的代码:

案例1 :(两种情况都是不同的,我试图做同样的事情。)

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

我没有收到任何错误,也没有任何反应。 我也尝试了以下内容,因为我实际上需要加载的类与其他(已经加载的)类进行交互。

案例2:

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

然后我这样加载:

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

或者像这样:

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

并尝试像这样调用main函数:

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

这里也没有任何反应。

任何可能发生的事情的线索?我已经阅读了这里的所有相关帖子以及许多其他没有运气的地方。

2 个答案:

答案 0 :(得分:1)

在OSGI框架中,有必要将OSGI类加载器添加为父类,如下所示:     ...     ClassLoader cl = new URLClassLoader(new URL [] {file.toURI()。toURL()},this.getClass()。getClassLoader());     ...

答案 1 :(得分:0)

在第一种情况下,我怀疑GuiLauncher类已经在类路径中,因此可能会被默认的类加载器加载。在设置动态类加载器之前尝试执行Class.forName() ,以确认没有可用的类。如果您在Eclipse中,则需要注意Eclipse类路径中不包含该类,这通常会发生。您可能需要编译一次,然后将.java.class文件移到其他位置以将其隐藏在Eclipse中!

案例2:

Class.forName("GuiLauncher");

将无法正常工作,因为这将使用系统类加载器。这个应该失败,因此我怀疑上面。您需要使用指定动态类加载器的other version of this method

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

以下代码适用于我。

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();
    }
  }
}

Plugin类在plugin子文件夹中编译,因此它不在用于运行Main的类路径上,如第一个Class.forName()所示。

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

并打印出来:

Nothing there! 
Plugin was invoked!