2011-04-05 26 views
2

我擁有引用第三方JAR的插件A.我試圖動態地從這個JAR從加載類的插件B.Eclipse RCP:另一個插件引用的庫中定義的動態加載類

我有這樣的事情從一類插件B:

myClass = getClass().getClassLoader().loadClass("com.foo.Bar"); 

這工作得很好,如果我想加載在插件A中定義的類,但是當嘗試加載插件A中引用的JAR中的類時,我得到ClassNotFoundException。

JAR位於類路徑上,並且在我不要試圖通過這個類加載器來動態加載。

任何想法?

在此先感謝。

回答

1

你的設置錯了。理想情況下,應該將第三方jar創建爲插件(File-> New->來自現有jar的插件),從而暴露jar中的類。然後設置A & B取決於它。

+0

您可能是對的,但這在我們的應用程序中不是可行的選項。對於我的問題,我決定不使用反射動態實例化類,而是使用代碼生成代替。 – lucks 2011-04-06 21:31:44

0

在插件A中,確保已經添加了jar來捆綁清單類路徑,然後確保導出包含在該jar中的包。

打開META-INF/MANIFEST -MF文件。你應該看到一個多頁面編輯器。轉到運行時選項卡並查看Classpath部分。然後請參閱導出的軟件包部分。然後進入Build頁面,並確保你的jar在Binary Build部分被選中。

+0

是的,它都在那裏。該設置在正常情況下工作......我在運行時動態加載類時遇到了問題,Bundle類加載器 – lucks 2011-04-06 21:29:13

+0

@lucks:您和其他人: - /曾經嘗試直接使用第三方JDBC驅動程序,而無需通過Eclipse框架?當我想到我必須採用的各種技巧來做到這一點時,我仍然不寒而慄... – thkala 2011-04-06 23:21:54

+0

如果bundle classloader不起作用,那麼您沒有得到正確的設置。仔細檢查我引用的所有部分。 – 2011-04-07 00:53:31

1

我認爲您的解決方案的關鍵是以下我在另一篇文章中閱讀,每個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行,這樣您就可以看到如何在類加載器中轉儲所有類...

相關問題