2

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

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

这是我正在使用的代码:

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

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

案例二:

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

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

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

这里也没有任何反应。

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

4

2 回答 2

1

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

于 2014-04-04T14:27:22.260 回答
0

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

情况 2:

Class.forName("GuiLauncher");

不会像您期望的那样工作,因为这将使用系统类加载器。这应该失败,因此我在上面怀疑。您需要使用此方法的其他版本来指定您的动态类加载器:

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!
于 2012-10-03T18:19:15.293 回答