我認爲您的解決方案的關鍵是以下我在另一篇文章中閱讀,每個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