2008-10-08 177 views

回答

85

如果您正在嘗試創建一個包含您的應用程序並且它是必需的庫的jar文件,那麼有兩種方法(我知道這樣做)。第一個是One-Jar,它使用特殊的類加載器來實現罐子的嵌套。第二個是UberJar(或Shade),它會展開包含的庫並將所有類放入頂級jar包中。

我還應該提到,UberJar和Shade分別是Maven1和Maven2的插件。如下所述,您還可以使用程序集插件(實際上它更強大,但要正確配置要困難得多)。

+64

所以我們現在在5年後。看起來這仍然是事實。非常傷心:( – T3rm1 2013-08-06 06:49:19

+1

我知道現在一天的最好方法是使用IntelliJ罐子工件,它從相關罐子中提取所有類並將它們放入一個罐子中。 – enl8enmentnow 2014-01-25 17:50:05

+1

這在某些情況下不可能,例如何時你使用的JCE實現像BouncyCastle那樣需要簽名 – debuti 2014-08-11 11:44:43

6

不是沒有寫你自己的類加載器。您可以將jar添加到jar的類路徑中,但它們必須位於同一位置,不包含在主jar中。

2

您需要構建一個自定義類加載器來執行此操作或支持此功能的第三方庫。你最好的選擇是從運行時中提取jar並將它們添加到classpath中(或者將它們添加到classpath中)。

1

我打算建議在同一級別提取所有文件,然後在結果中製作一個jar文件,因爲包系統應該保持它們整齊分離。 這將是手動的方式,我想史蒂夫指出的工具會做得很好。

2

我使用我的java版本的maven,它有一個名爲maven assembly plugin的插件。

它做什麼你問,但像一些其他的建議形容 - 本質爆炸所有的依賴罐子,並將它們重新組合成一個單一的罐子

49

你不想使用這些「爆炸JAR內容」的解決方案。他們肯定很難看到東西(因爲一切都在同一層次爆炸)。此外,可能會出現命名衝突(如果人們使用適當的軟件包,則不會發生這種衝突,但您無法始終控制這種衝突)。

您需要的功能是top 25 Sun RFEsRFE 4648386之一,Sun以其無限的智慧將其指定爲低優先級。我們只能希望Sun喚醒...

與此同時,我遇到的最好的解決方案(我希望Sun將在JDK中複製)是使用自定義類加載器JarClassLoader

22

使用zipgroupfileset標籤(使用相同的屬性,爲文件集標籤);它將解壓縮目錄中的所有文件並添加到新的存檔文件中。 更多信息:http://ant.apache.org/manual/Tasks/zip.html

這是要解決的jar-IN-A-JAR問題非常有用的方式 - 我知道,因爲我試圖找出該怎麼做用Google搜索這個確切的StackOverflow問題。如果要打包一個罐子或瓶子與螞蟻的一個內置的jar的文件夾,然後忘掉這一切的類路徑或第三方插件的東西,你要做的是這樣的(以螞蟻):

<jar destfile="your.jar" basedir="java/dir"> 
    ... 
    <zipgroupfileset dir="dir/of/jars" /> 
</jar> 
8

如果你正在用ant(我使用eclipse中的ant)構建,你可以通過向ant添加額外的jar文件 來添加它們...... 如果你有一個項目保持不一定是最好的方法由多人組成,但它適用於單人項目,並且非常簡單。

例如我的目標是正在建的.jar文件是:

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}"> 
    <manifest> 
     <attribute name="Author" value="ntg"/> 
     ................................ 
     <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/> 
    </manifest> 
</jar> 

我只是增加了一條線,使其:

<jar ...."> 
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/> 
    <manifest> 
     ................................ 
    </manifest> 
</jar> 

其中

<property name="external-lib-dir" value="C:\...\eclipseWorkspace\Filter\external\...\lib" /> 

是與外部罐子的dir。 就是這樣...

26

經過一番研究,我發現了一種不需要maven或任何第三方擴展/程序的方法。

您可以在清單文件中使用「Class-Path」。

例如:

創建清單文件MANIFEST.MF

Manifest-Version: 1.0 
Created-By: Bundle 
Class-Path: ./custom_lib.jar 
Main-Class: YourMainClass 

編譯所有的類和運行jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

c代表創建歸檔 f表示要指定文件 v用於詳細輸入 m意味着我們將pa ss自定義清單文件

確保您在jar包中包含lib。你應該能夠以正常的方式運行jar。

基於:http://www.ibm.com/developerworks/library/j-5things6/

您需要了解的類路徑中的所有其他信息你覺得here

1

嗯,是,如果你正在使用Eclipse的一個非常簡單的方法。

將項目導出爲「Runnable」Jar文件(在Eclipse中右鍵單擊項目文件夾,選擇「導出...」)。當您配置導出設置時,請務必選擇「將所需庫提取到生成的Jar中」。請記住,選擇「Extract ...」和而不是「包裝所需的庫...」。

此外:您必須在導出設置中選擇運行配置。因此,您可以在某個類中始終創建一個空的main(),並將其用於您的運行配置。

無論如何,它不是保證 100%的時間工作 - 因爲你會注意到一個彈出消息,告訴你確保你檢查你包括的Jar文件的許可證和一些關於不復制籤名文件。但是,我一直在做這個並從未遇到過問題。

2

如果你有eclpise IDE,你只需要導出你的JAR並選擇「Package Required libraries into generated JAR」。 eclipse會自動將所需的依賴JAR添加到生成的JAR中,並生成一些自動加載這些JAR的eclipse自定義類加載器。