您好我正在创建一个插件,需要动态加载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在实现这一目标方面有多大帮助?
提前致谢!
答案 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导出的包可用于类路径上的其他包,但所有类都将被加载。