如何动态加载目录中的所有jar?

时间:2014-02-20 09:56:47

标签: java eclipse-plugin osgi urlclassloader

您好我正在创建一个插件,需要动态加载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在实现这一目标方面有多大帮助?

提前致谢!

2 个答案:

答案 0 :(得分:3)

您需要首先加载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");

答案 1 :(得分:1)

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