有時候,因爲項目的須要,咱們會將源碼編譯後以工具包(class打成jar包)的形式對外提供,此時,
你的 jar 包不必定要是可執行的,只要能經過編譯,能被別人以 import 的方式調用就好了。但還有的
狀況是,咱們的 jar 包是要可執行的,即能直接在 cmd 下直接運行。前者的打包很簡單,在 eclipse 中,
直接選中要打包的 java 文件和其它資源、依賴文件, export → Java → JAR file 便可。須要注意的是,
這種方式導出的 jar 包是不可執行的,好比你執行以下的語句:
java -jar test.jar
java -classpath test.jar com.test_maven.App
會直接報錯:沒法找到主類或者找不到 xxx 依賴包/類,這是因爲你沒有定義 MANIFEST.MF 資源描述文件所致,
或者你直接把依賴的 jar 包打進了你最終的 jar,而這種嵌套的依賴 jar 包是不能直接被程序 import 識別的。
下面咱們看看如何在 eclipse 中構建一個可執行的 jar 包。html
(1)最簡單的仍是依賴於 eclipse 的導出功能:java
export → java → Runnable JAR file,這種形式的導出程序員
能夠經過 lanuch configuration 指定一個 MainClass,並會自動生成 MANIFEST.MF ,並且會幫你把依賴的 jar 包解壓出來,一併打進最終的 jar 包,這樣就能被你的代碼 import 引用了。apache
(2)上述方法是 eclipse 自帶的,eclipse 也有個專門的插件叫作 Fat Jar,支持許多定製化的功能,json
具體請參見下面的連接。可是這個插件有些缺陷,好比修改源碼後若是你不 clean & rebuild project,緩存
它會使用緩存從新打包,這樣你的編譯代碼仍是老的,會形成執行錯誤,並且這樣是十分不方便的。oracle
用Fat Jar Eclipse Plug-In打包可執行jar文件eclipse
http://8366.iteye.com/blog/480652maven
(3)稍微大點的項目都會用 maven 或者 ant 來構建,在 maven 工程中,咱們也能夠很方便的打包成可執行的 jar
包。默認Maven生成的JAR包只包含了編譯生成的.class文件和項目資源文件,而要獲得一個能夠直接在命令行經過
java命令運行的JAR文件,還要知足兩個條件:工具
Maven有好幾個插件能幫助用戶完成上述任務,不過用起來最方便的仍是maven-shade-plugin,它可讓用戶配置
Main-Class的值,而後在打包的時候將值填入/META-INF/MANIFEST.MF文件。關於項目的依賴,它很聰明地將依賴
JAR文件所有解壓後,再將獲得的.class文件連同當前項目的.class文件一塊兒合併到最終的CLI包中,這樣,在執行CLI JAR文件的時候,全部須要的類就都在Classpath中了。下面是一個配置樣例:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.juvenxu.mavenbook.HelloWorldCli</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
上述例子中的,個人Main-Class是com.juvenxu.mavenbook.HelloWorldCli,構建完成後,對應於一個常規的
hello-world-1.0.jar文件,我還獲得了一個hello-world-1.0-cli.jar文件。細心的讀者可能已經注意到了,這裏用的
是cli這個classifier。最後,我能夠經過java -jar hello-world-1.0-cli.jar命令運行程序。固然了,若是你須要更加自由
的打包方式,那就用 maven-assembly-plugin 吧。它支持各類打包文件格式,包括zip、tar.gz、tar.bz2等等,經過一個打包
描述文件(例如 src/main/assembly.xml),它可以幫助用戶選擇具體打包哪些文件集合、依賴、模塊、和甚至本地倉庫文件,
每一個項的具體打包路徑用戶也能自由控制。好比下面的配置經過設置 assembly 文件的配置節點 dependencySets/includes,來實現 maven build 生成的 jar 包只包含指定的 jar 依賴。
<assembly ... ooxx> <fileSets> </fileSets> <dependencySets> <dependencySet> <unpack>false</unpack> <outputDirectory>lib</outputDirectory> <scope>runtime</scope> <includes> <include>groupId:artifactId</include> </includes> </dependencySet> </dependencySets> </assembly>
具體請參見:
Maven實戰(九)——打包的技巧
http://www.infoq.com/cn/news/2011/06/xxb-maven-9-package
maven發佈 jar類型的工程
http://mengyunshuitian.iteye.com/blog/1759864
maven assembly plugin dependencySet with transitive dependencies
http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#dependencySet
(4)可使用兩個 Maven 插件幫助您完成:maven-jar-plugin 和 maven-dependency-plugin。
maven-jar-plugin 能夠作不少事情,但在這裏,咱們只對使用它來修改默認 MANIFEST.MF 文件的內容感興趣。
在您的 POM 文件的插件部分添加清單 1 所示代碼:
清單 1. 使用 maven-jar-plugin 修改 MANIFEST.MF
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.mypackage.MyClass</mainClass> </manifest> </archive> </configuration> </plugin>
全部 Maven 插件經過一個 <configuration> 元素公佈了其配置,在本例中,maven-jar-plugin 修改它的 archive 屬性,
特別是存檔文件的 manifest 屬性,它控制 MANIFEST.MF 文件的內容。包括 3 個元素:
addClassPath:將該元素設置爲 true 告知 maven-jar-plugin 添加一個 Class-Path 元素到 MANIFEST.MF 文件,以及在
Class-Path 元素中包括全部依賴項。
classpathPrefix:若是您計劃在同一目錄下包含有您的全部依賴項,做爲您將構建的 JAR,那麼您能夠忽略它;不然使用
classpathPrefix 來指定全部依賴 JAR 文件的前綴。在清單 1 中,classpathPrefix 指出,相對存檔文件,全部的依賴項
應該位於 「lib」 文件夾。
mainClass:當用戶使用 lib 命令執行 JAR 文件時,使用該元素定義將要執行的類名。
當您使用這 3 個元素配置好了 MANIFEST.MF 文件以後,下一步是將全部的依賴項複製到 lib 文件夾。爲此,使用
maven-dependency-plugin,如清單 2 所示:
清單 2. 使用 maven-dependency-plugin 將依賴項複製到庫
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy</id> <phase>install</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory> ${project.build.directory}/lib </outputDirectory> </configuration> </execution> </executions> </plugin>
maven-dependency-plugin 有一個 copy-dependencies,目標是將您的依賴項複製到您所選擇的目錄。本例中,我將依賴項複製到
build 目錄下的 lib 目錄(project-home/target/lib)。
將您的依賴項和修改的 MANIFEST.MF 放在適當的位置後,您就能夠用一個簡單的命令啓動應用程序:
java -jar jarfilename.jar
更多技巧,您能夠參考:
關於 Apache Maven 您不知道的 5 件事
http://www.ibm.com/developerworks/cn/java/j-5things13/
(5)固然了,若是你不怕麻煩的話,手動打包,本身創建、維護 MANIFEST.MF 文件也是能夠的,你能夠參考以下連接:
http://blog.csdn.net/mango_song/article/details/8531389
http://gushuizerotoone.iteye.com/blog/1757002
(6)把包發佈到 nexus
項目上右鍵 → run as → maven build
附:Maven的座標GAV(groupId, artifactId, version)定義
pom定義了最小的maven元素,容許groupId,artifactId,version。在 POM 中,groupId, artifactId, packaging, version 叫做 maven 座標,它能惟一的肯定一個項目。有了 maven 座標,咱們就能夠用它來指定咱們的項目所依賴的其餘項目,插件,或者父項目。通常 maven 座標寫成以下的格式:
groupId:artifactId:packaging:version
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.2</version> <classifier>jdk15</classifier> </dependency>
這樣配置便可找到json-lib-2.2.2-jdk15.jar ,其餘的就不解釋了,應該明白他的用途了吧。
POM關係:
主要爲依賴,繼承,合成
REF:
使用maven插件對java工程進行打包
http://chenzhou123520.iteye.com/blog/1706242
關於如何從jar包中讀取配置、屬性文件,請參考:
http://my.oschina.net/leejun2005/blog/95186
Apache Maven 入門篇(下)
http://www.oracle.com/technetwork/cn/community/java/apache-maven-getting-started-2-405568-zhs.html
maven 配置篇 之pom.xml(一)
http://zyl.iteye.com/blog/41754
Maven最佳實踐:劃分模塊
http://juvenshun.iteye.com/blog/305865
在Eclipse中建立Maven多模塊工程的例子
http://www.blogways.net/blog/2013/05/13/maven-multi-modules-demo.html
每一個程序員都該學會的Maven知識
https://mp.weixin.qq.com/s/UnMyH65RtWPHdRHMfIsxlg
Maven 虐我千百遍,我待 Maven 如初戀