【问题标题】:How to load all the jars from a directory dynamically?如何动态加载目录中的所有jar?
【发布时间】:2014-03-21 04:25:25
【问题描述】:

您好,我正在创建一个插件,它需要动态加载 jar 并访问这些 jar 的类和方法。我尝试使用 URLClassLoader 并且能够加载如下所示的类

URL myJarFile = new URL("jar","","file:"+jarPath);
URLClassLoader sysLoader =(URLClassLoader)ClassLoader.getSystemClassLoader();
Class sysClass = URLClassLoader.class;
Method sysMethod = sysClass.getDeclaredMethod("addURL", new Class[]{URL.class});
sysMethod.setAccessible(true);
sysMethod.invoke(sysLoader, new Object[]{myJarFile});

但是这样做的问题是我们必须通过单独指定它们的名称来将类加载到 classLoader 中。 我想要的是从类路径中的所有 jar 中加载所有类并随时访问它们。

是否可以使用 URLClassLoader?如果不是,其他选择是什么? OSGI 对实现这一目标有多大帮助?

提前致谢!

【问题讨论】:

  • “我想要的是从类路径中的所有 jar 中加载所有类并随时访问它们。”为什么???如果不了解您的动机,您的问题将无法回答。如果您正在尝试构建一个能够添加插件的可扩展应用程序,那么您应该绝对使用 OSGi。

标签: java eclipse-plugin osgi urlclassloader


【解决方案1】:

您需要先加载您的 jar,然后从那里加载所需的类。

URL myJarFile = new URL("jar","","file:"+jarPath);
URLClassLoader child = new URLClassLoader (myJarFile , this.getClass().getClassLoader());
Class classToLoad = Class.forName ("com.MyClass", true, child);
Method method = classToLoad.getDeclaredMethod ("myMethod");
Object instance = classToLoad.newInstance ();
Object result = method.invoke (instance);

那么可以先获取jar文件中所有类的列表:

List<String> classNames=new ArrayList<String>();
ZipInputStream zip=new ZipInputStream(new FileInputStream("/path/to/jar/file.jar"));
for(ZipEntry entry=zip.getNextEntry();entry!=null;entry=zip.getNextEntry())
    if(entry.getName().endsWith(".class") && !entry.isDirectory()) {
        StringBuilder className=new StringBuilder();
        for(String part : entry.getName().split("/")) {
            if(className.length() != 0)
                className.append(".");
            className.append(part);
            if(part.endsWith(".class"))
                className.setLength(className.length()-".class".length());
        }
        classNames.add(className.toString());
    }

一旦你有了你的班级列表,请执行以下操作:

File file = new File("Absolute Path to your jar");  
            URL url = file.toURI().toURL();  
            URL[] urls = {url};  
            ClassLoader loader = new URLClassLoader(urls);  
            Class myClass = loader.loadClass(classNames.get(0));  
            System.out.println("Executing...");  
            Object tester = myClass.newInstance(); 
        System.out.println("Test");

【讨论】:

  • 抓住了。我不知道要加载什么类。这个 jar 中有很多类,我希望所有类都可以在类路径中使用...
  • 感谢@Mobility。这将真正解决加载所有类的问题。但是现在,如果我想以某种方式访问​​ laoded jar 的某个特定类,比如SomeJarClass obj = SomeJarClass.getInstance(),这应该可以工作,因为 该 jar 的所有类都已加载。但是,它再次给出了一个找不到类的异常。
  • 我找到了解决方案。实际上我打电话给班级的方式是错误的。现在我可以装罐子了。加载一个主类,该主类在内部使用来自其他 jar 的其他类的实例,并且它们都在运行时可用。
【解决方案2】:

Apache Felix File Install 可能正是您想要的。它将监视指定目录并动态加载其中的任何包。只有 bundle 导出的包对类路径上的其他 bundle 可用,但所有的类都会被加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-02
    • 2012-11-10
    • 2010-10-17
    • 2014-12-24
    • 2013-08-01
    • 2012-01-24
    • 2020-06-08
    • 1970-01-01
    相关资源
    最近更新 更多