我正在尝试从jar加载一个类,我正在使用classLoader。
我有这部分代码用于准备classLoader:
private void loadClass(){
try{
JarFile jarFile = new JarFile( Path);
Enumeration e = jarFile.entries();
URL[] urls = { new URL("jar:file:" + Path +"!/") };
classLoader = URLClassLoader.newInstance(urls);
} catch (MalformedURLException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
现在我加载一个类,然后尝试获取一个新实例
....
loadClass();
Class device = classLoader.loadClass( "org.myPackage.MyClass");
MyMotherClass Device = ( MyMotherClass) device.newInstance();
...
MyClass扩展了MyMotherClass,当我执行classLoader.loadClass(“org.myPackage.MyClass”)时,MyMotherClass位于classLoader中。 此刻,没事。
现在,在device.newInstance()中,我得到一个例外。问题是MyClass使用的其他类不在类路径中。
我该怎么办?
我有另一个方法在classLoader中加载所有需要的类,但是当我得到新实例时它不起作用。 我不能改变MyClass和其他人
答案 0 :(得分:2)
这是我用来在运行时动态加载jar的一些代码。我利用反射来规避你不应该这样做的事实(即,在JVM启动后修改类路径)。只需将my.proprietary.exception
更改为合理的内容即可。
/*
* Adds the supplied library to java.class.path.
* This is benign if the library is already loaded.
*/
public static synchronized void loadLibrary(java.io.File jar) throws my.proprietary.exception
{
try {
/*We are using reflection here to circumvent encapsulation; addURL is not public*/
java.net.URLClassLoader loader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
java.net.URL url = jar.toURI().toURL();
/*Disallow if already loaded*/
for (java.net.URL it : java.util.Arrays.asList(loader.getURLs())){
if (it.equals(url)){
return;
}
}
java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
method.setAccessible(true); /*promote the method to public access*/
method.invoke(loader, new Object[]{url});
} catch (final NoSuchMethodException |
java.lang.IllegalAccessException |
java.net.MalformedURLException |
java.lang.reflect.InvocationTargetException e){
throw new my.proprietary.exception(e.getMessage());
}
}