我认为您的解决方案的关键是以下我在另一篇文章中阅读,每个Eclipse插件保持它自己的类加载器。
因此,我可以告诉你我的Eclipse(3.7)插件为动态加载做什么,我不确定是否可以“适合”到您的需求。基本上,我的插件做加密/解密。作为一项新的增强功能,我允许用户通过FileDialog加载一个或多个Jar文件,其中每个jar文件都使用URLClassLoader加载。创建我的“自定义”类加载器使用以下行:
this.FQCNLoader = new URLClassLoader (getFQCNUrls(), this.getClass().getClassLoader());
的关键是在作为第二个参数的Eclipse插件的ClassLoader通过......这意味着你的“自定义”类加载器具有Eclipse插件的CLASSPATH加上你添加的任何URL(getter getFQCNUrls()返回一个URL [])。
另一个关键问题是,我在一个视图中维护“自定义”类加载器,我知道该视图持续了Eclipse插件的整个生命周期。该视图位于需要引用动态* .jar类的所有代码之上。
所以,你需要沿着同样的路线做点什么。你的“自定义”类加载器需要在pluginA和pluginB之上的类中生存。另外,我觉得,因为每个插件有它自己的类加载器,你实际上将需要建立一个“自定义”类加载器,做类似以下内容:
1.) Let pluginB load dynamic *.jar/classes. Convert into URL[].
2.) Create "custom" loader, pass in pluginB URL[] PLUS pluginA classloader.
这里是在addURL()方法我查看构建“自定义”类加载器的类...它有点难看,因为我写它很匆忙,并且每次用户加载*时都会重新生成“自定义”类加载器。罐子,但它的工作在Eclipse和无OSGi的:
private int URLCount = 0;
private URL[] FQCNUrls = new URL[10];
private ClassLoader FQCNLoader = new URLClassLoader (this.FQCNUrls);
...Lots of code...
public void addURL (URL theURL) throws IOException {
//CPTest lclsTest = new CPTest();
if (getURLCount() == 0) {
getFQCNUrls()[getURLCount()] = theURL;
setURLCount (1);
}
else {
boolean lisThere = false;
for (int i = 0; i < getURLCount(); i++) {
if (getFQCNUrls()[i].toString().equalsIgnoreCase(theURL.toString())) {
lisThere = true;
}
}
if (lisThere) {
System.out.println ("File URL [" + theURL.toString() + "] already on the CLASSPATH!");
}
else {
getFQCNUrls()[getURLCount()] = theURL;
setURLCount (getURLCount()+1);
}
}
// CLEAR : Null out the classloader...
this.FQCNLoader = null;
// BUILD/RE-BUILD : the classloader...
this.FQCNLoader = new URLClassLoader (getFQCNUrls(), this.getClass().getClassLoader());
//try {
// System.out.println ("---------------------------------------------------------------------------");
// System.out.println ("Current Working Directory.............[" + System.getProperty ("user.dir") + "]");
// System.out.println ("---------------------------------------------------------------------------");
// System.out.println ("this.classes []! ");
// lclsTest.dumpClasses (this.getClass().getClassLoader());
// System.out.println ("---------------------------------------------------------------------------");
//
// System.out.println ("---------------------------------------------------------------------------");
// System.out.println ("File URL [" + theURL.toString() + "] added! ");
// lclsTest.dumpClasses (this.FQCNLoader);
// System.out.println ("---------------------------------------------------------------------------");
// System.out.println ("---------------------------------------------------------------------------");
// System.out.println ("ClassLoader.getSystemClassLoader() ");
// lclsTest.dumpClasses (ClassLoader.getSystemClassLoader());
// System.out.println ("---------------------------------------------------------------------------");
// Class cls = this.FQCNLoader.loadClass ("com.lmig.RRFECF.pso.security.nonproduction.CM_RRFECF_development_securitykey");
// Class cls = Class.forName(theFQCN, false, theClsLoader);
// theObjectKey = (Object) theClsLoader.loadClass(theFQCN);
//}
//catch (Exception e) {
//// TODO Auto-generated catch block
// e.printStackTrace();
//}
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(getFQCNLoader(), new Object[] {
theURL
});
}
catch (Throwable t) {
t.printStackTrace();
throw new IOException(
"Error, could not add URL to system classloader");
}
}
BTW,我鼓励你抢CPTest类在第一行注释掉,它是无价的我如何洞察不同的类加载器和什么在他们身上。我在代码中留下了Sysout行,这样您就可以看到如何在类加载器中转储所有类...
您可能是对的,但这在我们的应用程序中不是可行的选项。对于我的问题,我决定不使用反射动态实例化类,而是使用代码生成代替。 – lucks 2011-04-06 21:31:44