2011-08-04 45 views
0

我遵循Create cross platform Java SWT Application中描述的步驟。我創建了一個包含swt_browser.jar的jar,其中只包含使用swt庫的我的類。然後我添加了其他特定於platrom的swt罐子。 我使用下面的代碼來加載swt_browser.jar和平臺特定的swt庫jar。但不知何故呼籲加載類SWTBrowser抱怨:jar-in-jar類加載問題

java.lang.ClassNotFoundException: org.eclipse.swt.widgets.Layout 

你能告訴我做錯了什麼嗎?

-----加載SWT罐子代碼-------

ClassLoader parent = Main.class.getClassLoader(); 
      URL.setURLStreamHandlerFactory(new RsrcURLStreamHandlerFactory(parent)); 
      URL swtBrowserFileUrl = new URL("rsrc:swt_browser.jar"); 
      URL swtFileUrl = new URL("rsrc:" + swtFileName); 

      ClassLoader cl = new URLClassLoader(new URL[]{swtBrowserFileUrl, swtFileUrl}, parent); 
      Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); 
      addUrlMethod.setAccessible(true); 
      addUrlMethod.invoke(cl, swtBrowserFileUrl); 
      addUrlMethod.invoke(cl, swtFileUrl); 
      Thread.currentThread().setContextClassLoader(cl); 
      try { 
       // Check we can now load the SWT class -this check passes! 
       Class.forName("org.eclipse.swt.widgets.Layout", true, cl); 
      } catch (ClassNotFoundException exx) { 
       System.err.println("Launch failed: Failed to load SWT class from jar: " + swtFileName); 
       throw new RuntimeException(exx); 
      } 

      //this line below throws exception : java.lang.ClassNotFoundException:  org.eclipse.swt.widgets.Layout 

      Class<?> c = Class.forName("com.sun.star.google.gui.SWTBrowser", true, cl); 

      Object obj = c.newInstance(); 
      Method run = c.getMethod("run", url.getClass()); //$NON-NLS-1$ 
      run.invoke(obj, new Object[]{url}); 

回答

2

你的罐子具有以下文件結構:

file structure

您正在設置的ClassLoaders:

  • Main classloader
    • SWT的類加載器

主類加載器擁有所有在其類路徑如下:

  • 您的應用程序類
  • 的罐子,在-JAR的類加載器

SWT類加載器在運行時構建,其類路徑中包含以下內容:

  • 的SWT類平臺

你的加載代碼詢問SWT類加載器加載一個SWT類的作品。但是,您然後要求它加載一個應用程序類。它不知道你的應用程序類,所以它委託給它的父類Main加載器。這管理加載你的應用程序類,然後嘗試引用一個SWT類。該引用由加載應用程序類的類加載器(Main classloader)處理。這不知道SWT類並引發異常。

您需要以不同方式打包應用程序。你需要有以下類加載器。

  • 主要的類加載器
    • SWT的類加載器

主類加載器擁有所有在其類路徑如下:

  • 一個單一的應用程序類處理建設SWT類加載器
  • 罐子,在-JAR的類加載器

的SWT類加載器在運行時構造並在其類路徑如下:

  • 的SWT類平臺
  • 您的應用程序類

這意味着當你加載你的應用程序類時,它將被SWT類加載器加載。這意味着,當您的應用引用SWT類時,會使用正確的類加載器。

對於這個工作的例子,你可以下載並檢查以下jar:https://github.com/downloads/mchr3k/org.intrace/intrace-ui.jar

編輯:https://github.com/mchr3k/org.intrace/blob/master/org.intrace/build.xml

特別:它生產intrace-ui.jar在這裏可以看到Ant構建文件,「jar」目標處理包裝。

+0

謝謝-i'll儘快做到這一點 - 我覺得有點累了,這就是爲什麼我感到困惑了一點,這個類加載複雜的過程... – othman

+0

我感到困惑!我不知道該放哪些東西! - 你可以給出一些代碼和更多解釋如何用一些代碼片段來封裝它? – othman

+0

我已經爲intrace-ui.jar添加了一個ant build腳本的鏈接。你能澄清一下你對此感到困惑嗎? – mchr