使用MAVEN打包可執(zhí)行的jar包

說明

非web項目中經(jīng)常遇到需要將工程打包成一個可執(zhí)行jar包(通過在命令行執(zhí)行java命令進(jìn)行啟動)的情況。
一個可執(zhí)行的jar包吭产,需要滿足以下條件:

在jar包中的/META-INF/MANIFEST.MF元數(shù)據(jù)文件中必須保護(hù)Main-Class啟動入口類信息
項目的所有依賴都必須包含在Classpath中判帮。即依賴必須都被描述MANIFEST于.MF文件中的Class-Path下
Maven中可以通過許多插件完成打包任務(wù)袱饭,如強大的maven-assembly-plugin等雌桑。具體使用方式,可以參見各插件的說明务荆。

基礎(chǔ)概念:maven的生命周期與插件

Maven將工程的構(gòu)建過程分為不同的生命周期(LifeCycle)妆距,每個生命周期中又劃分為不同的階段(Phase)。
LifyCycle之間互相獨立函匕,且沒有明確的順序關(guān)系娱据,而每個LifeCycle中的Phase間則存在明確的順序關(guān)系,且必須依序執(zhí)行盅惜。
Maven內(nèi)置了三個LifyCycle中剩,如default(build)構(gòu)建忌穿,clean清理, site生成文檔與站點。
以default為例咽安,其內(nèi)置的phase主要包含有: validate,compile,test,package,intergration-test,verify,install,deploy.這些phase在項目build時會依次執(zhí)行 伴网。

Maven所定義的LifeCycle與Phase只是抽象的概念蓬推,不涉及具體的功能妆棒。而功能的實現(xiàn)則由插件(Plugin)負(fù)責(zé)。

一個Plugin可以實現(xiàn)多個目標(biāo)(Goal), Goal可以綁定在多個Phase上, 每個Phase下也可以包含多個Goal沸伏「馍海可以將Phase視為Goal的容器。
Goal是Maven里面最小的任務(wù)單位毅糟,相關(guān)于Ant的target红选。Goal與Goal之間是互相獨立的。單獨執(zhí)行某個Goal不會導(dǎo)致其他Goal被執(zhí)行姆另。

當(dāng)我們對一個工程執(zhí)行打包命令mvn package時, maven將從validate階段開始喇肋,一個階段一個階段(compile, test)的執(zhí)行,直至到達(dá)package階段迹辐。
在執(zhí)行到compile階段時蝶防,插件maven-compiler-plugin的compile goal會被執(zhí)行,因為這個goal是綁定在compile階段明吩。
同理间学,當(dāng)執(zhí)行到package階段時,插件maven-dependency-plugin與maven-resources-plugin的相關(guān)goal都會被執(zhí)行印荔。

工程打包示例

目錄結(jié)構(gòu)示例

project/
      + src/main/java/
          + com.some.package
      + src/main/resources/
          - settings.properties
          - applicationContext.xml
          - startup.bat
      - pom.xml

打包后的期望結(jié)果

target/
        + conf/
            - settings.properties
            - applicationContext.xml
        + lib/
        - project.jar
        - startup.bat

project.jar中不包含配置文件低葫。

pom文件中打包相關(guān)的配置

<build>
        <plugins>

            <!-- 編譯插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                    <compilerArguments>
                        <verbose />
                        <bootclasspath>${java.home}/lib/rt.jar</bootclasspath>
                    </compilerArguments>
                </configuration>
            </plugin>

            <!-- 項目依賴插件  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <configuration>
                    <outputDirectory>${project.build.directory}/lib</outputDirectory>
                    <excludeTransitive>false</excludeTransitive> <!-- 表示是否不包含間接依賴的包 -->
                    <stripVersion>false</stripVersion> <!-- 去除版本信息 -->
                </configuration>

                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <!-- 拷貝項目依賴包到lib/目錄下 -->
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <excludeTransitive>false</excludeTransitive>
                            <stripVersion>false</stripVersion>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- 項目資源插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <encoding>UTF-8</encoding>
                            <!-- 拷貝項目src/main/resources/下,除.bat以外的所有文件到conf/目錄下 -->
                            <outputDirectory>${project.build.directory}/conf</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/resources/</directory>
                                    <filtering>true</filtering>
                                    <excludes>
                                        <exclude>*.bat</exclude>
                                    </excludes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                    <execution>
                        <id>copy-command</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <encoding>UTF-8</encoding>
                            <!-- 只拷貝項目src/main/resources/目錄下的.bat文件到輸出目錄下 -->
                            <outputDirectory>${project.build.directory}</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/resources/</directory>
                                    <filtering>true</filtering>
                                    <includes>
                                        <include>*.bat</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- 打包插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <!-- 生成MANIFEST.MF的設(shè)置 -->
                        <manifest>
                            <!-- 為依賴包添加路徑, 這些路徑會寫在MANIFEST文件的Class-Path下 -->
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <!-- jar啟動入口類-->
                            <mainClass>com.some.package.some.class.Main</mainClass>
                        </manifest>
                        <manifestEntries>
                            <!-- 在Class-Path下添加配置文件的路徑 -->
                            <Class-Path>conf/</Class-Path>
                        </manifestEntries>
                    </archive>
                    <includes>
                        <!-- 打jar包時仍律,只打包class文件 -->
                        <include>**/*.class</include>
                    </includes>
                </configuration>
            </plugin>

        </plugins>

        <!-- 解決eclipse下maven插件兼容性問題 -->
        <pluginManagement>
            <plugins>
                <!-- Ignore/Execute plugin execution -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <!-- copy-dependency plugin -->
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>org.apache.maven.plugins</groupId>
                                        <artifactId>maven-dependency-plugin</artifactId>
                                        <versionRange>[1.0.0,)</versionRange>
                                        <goals>
                                            <goal>copy-dependencies</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore />
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

打包命令mvn clean package
附錄1 啟動命令bat文件編寫

REM 關(guān)閉輸出
@echo off

REM 設(shè)置啟動時使用的jdk嘿悬。如果不設(shè)置,則使用系統(tǒng)變量中設(shè)置的jdk
set path=../jdk.1.7.80/bin
set classpath=../jdk.1.7.80/jre/lib

REM 最基本的jar包啟動命令水泉,使用MANIFEST中的入口類啟動
java -jar project.jar

REM 指定jar包的某個類作為入口啟動
java -cp project.jar some.package.some.class.MyClass

REM 設(shè)置jvm參數(shù)并啟動jar包
java -Xms256m -Xmx512m -jar project.jar

REM 開啟輸出
echo on

附錄2 maven打包時的文件拷貝

通常打包外部資源文件時鹊漠,都使用maven-dependency-plugin或是maven-resources-plugin插件。但是項目中遇見一個問題茶行,在打包jnotify的動態(tài)鏈接庫時躯概,使用上面兩個插件進(jìn)行文件拷貝時,程序會無法識別到打包后dll文件畔师。
多次嘗試后使用了maven-antrun-plugin進(jìn)行拷貝娶靡,問題得到解決。其拷貝配置如下:

<plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.7</version>  
                <executions>  
                    <execution>
                        <id>copy-native-libraries</id>  
                        <phase>package</phase>   
                        <goals>  
                            <goal>run</goal>  
                        </goals> 
                        <configuration>  
                            <target>  
                                <echo message="copy native libraries" />
                                <copy todir="${project.build.directory}/lib">  
                                    <fileset dir="${basedir}/lib"></fileset>  
                                </copy>  
                            </target>  
                        </configuration> 
                    </execution>  
                </executions>  
            </plugin>

首先說明一下 這篇文章我是轉(zhuǎn)載
作者:200cc
鏈接:http://www.reibang.com/p/afb79650b606
來源:簡書
著作權(quán)歸作者所有看锉。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)姿锭,非商業(yè)轉(zhuǎn)載請注明出處塔鳍。
還有一片文章也是不錯挺詳細(xì)的 雖然我沒打包起來.https://my.oschina.net/simpleton/blog/607776

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市呻此,隨后出現(xiàn)的幾起案子轮纫,更是在濱河造成了極大的恐慌,老刑警劉巖焚鲜,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掌唾,死亡現(xiàn)場離奇詭異,居然都是意外死亡忿磅,警方通過查閱死者的電腦和手機糯彬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來葱她,“玉大人撩扒,你說我怎么就攤上這事《中” “怎么了搓谆?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長豪墅。 經(jīng)常有香客問我泉手,道長,這世上最難降的妖魔是什么但校? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任螃诅,我火速辦了婚禮,結(jié)果婚禮上状囱,老公的妹妹穿的比我還像新娘术裸。我一直安慰自己,他們只是感情好亭枷,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布袭艺。 她就那樣靜靜地躺著,像睡著了一般叨粘。 火紅的嫁衣襯著肌膚如雪猾编。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天升敲,我揣著相機與錄音答倡,去河邊找鬼。 笑死驴党,一個胖子當(dāng)著我的面吹牛瘪撇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼倔既,長吁一口氣:“原來是場噩夢啊……” “哼恕曲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起渤涌,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤佩谣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后实蓬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茸俭,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年瞳秽,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓣履。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片率翅。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡练俐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出冕臭,到底是詐尸還是另有隱情腺晾,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布辜贵,位于F島的核電站悯蝉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏托慨。R本人自食惡果不足惜鼻由,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厚棵。 院中可真熱鬧蕉世,春花似錦、人聲如沸婆硬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彬犯。三九已至向楼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谐区,已是汗流浹背湖蜕。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宋列,地道東北人昭抒。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戈鲁。 傳聞我的和親對象是個殘疾皇子仇参,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 說明 非web項目中經(jīng)常遇到需要將工程打包成一個可執(zhí)行jar包(通過在命令行執(zhí)行java命令進(jìn)行啟動)的情0000...
    200cc閱讀 26,957評論 0 19
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)婆殿,斷路器诈乒,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • 所有項目的構(gòu)建都是有生命周期的,這個生命周期包括:項目清理婆芦、初始化怕磨、編譯、測試消约、打包肠鲫、集成測試、驗證或粮、部署导饲、站點生...
    zlcook閱讀 2,761評論 0 21
  • Maven編譯代碼的相關(guān)命令 第一、main目錄下的主代碼編寫完畢后氯材,使用Maven進(jìn)行編譯渣锦,在項目根目錄下運行命...
    加油小杜閱讀 1,172評論 0 2
  • Maven簡單介紹 Maven是一個項目管理工具。強大氢哮,但是很容易使用袋毙。 它包含了: 一個項目對象模型 (Proj...
    高公子Daniel閱讀 4,228評論 4 60