idea和gradle打包jar方法
前言
這幾天目前正在做的這個專案差不多編碼已經大致的完成了,需要的就是把專案打包成jar包,研究了幾天如何打包jar,遇到了很多問題,最終打包成功,下面分享給大家。
一 Idea打包jar
因為本人用的開發環境是IntelliJ IDEA,開始的時候研究了一下利用這個開發工具進行打包
首先按F4或者點選IDEA右上角這地方
進入專案結構管理器
選擇這裡面的Artifacts。開始我完全不知道Artifacts是什麼東西,後來查閱了點資料:Artifacts是maven中的一個概念,表示某個module要如何打包,例如war exploded、war、jar、ear等等這種打包形式;意思我理解的就是Artifacts就是告訴我們的程式因該如何打包這個專案。
之後新建一個Artifacts
這有兩個選項選擇第二個,從模組中引入,點選進去後會有一些設定,如下:
module是你需要打成jar包的專案
MainClass是執行的主函式,如果不需要執行則可以不選擇
jar files from libraries是專案打包的方式,下面選項大致的含義:
1:extract to the target jar:把所有檔案倒入進一個jar包裡
2:copy to the。。。。:把專案的依賴包匯出和專案一個目錄,通過MANIFEST.MF檔案來引用jar包。
這裡如果你的專案需要打成一個可執行的jar包推薦第二種,反之第一種。
設定完之後,就會新建一個xxx:jar,並進入進入xxx:jar的編輯頁面
在我們需要進行一個輸出目錄佈局的設定,我們可以看到,已經編譯好的專案的jar檔案(我的是eachend.jar)和其他匯入的jar包混到一起的,很雜,我是點選output layout下最左邊的資料夾圖示新建了一個lib檔案,把其他jar包拖拽進來(建議,也可以直接點OK完成)
但是我們這樣做的話依賴的jar包的目錄就會產生變化,這時候我們需要選中我們專案,在下方然後修改MANIFEST.MF中的Class Path
修改成OK
到了這一步後Artifacts是寫好了,儲存之後就可以用來生成jar檔案
點選build Artifacts後選擇你剛剛生成的artifacts
build後就會在out的目錄下生成對應的jar檔案
最後進入專案目錄 輸入命令java -jar XXX.jar 就可以跑起來了 如下
二 gradle打包jar
本以為專案打成jar包並且可以完美運行了後,這事就差不多完了,可是專案組長說:你這樣打包是可以,但是如果其他人用Eclipes來開發的話,就不管用了。。。。。。哎,好不容易搞出來的一個方法被pass掉了,無奈之下就只有另換方法。
因為專案我是用的gradle構建的,第一時間想起了用gradle打包。
利用gradle進行打包其實非常非常簡單,但是因為我平常只是簡單用它來導包,以及構建專案,它的基本的一些東西不是很清楚,所以走了些彎路花了大半天的時間才搞出來,所以說有時候需要了解一下你所用的東西的一些基礎和原理。
在build,gradle中首先需要加上
apply plugin: 'java'
apply plugin: 'idea'
來定義你自己專案使用的外掛,apply plugin: 'idea'用於把專案構建成idea專案,apply plugin: 'java'用於新增Java外掛,以及一些內建任務,打包jar就要用到這裡的外掛。
version = '1.0'
repositories {
mavenCentral()
}
這裡用來宣告版本號以及新增maven中心倉庫地址
dependencies {
compile 。。。。。。。
}
這裡來新增專案所需要的依賴包
jar {
String someString = ''
configurations.runtime.each {someString = someString + " lib\\"+it.name} //遍歷專案的所有依賴的jar包賦值給變數someString
manifest {
attributes 'Main-Class': 'com.each.dubboMainEnd'
attributes 'Class-Path': someString
}
}
打包的時候,這個地方很重要,用來設定jar檔案的相關屬性,這個地方把我坑了有點久,最後補了下gradle的基礎知識,就搞出來了,這篇部落格寫gradle基礎寫的還可以,推薦給大家看看http://www.open-open.com/lib/view/open1447139848053.html
首先這定義了一個someString用來存放依賴包的資訊,通過configurations.runtime拿到所有的執行時的依賴jar包,然後.each遍歷他,通過it.name獲取到每個的jar包的name,賦值。
manifest即是編譯完成後生成jar包中的MANIFEST.MF配置資訊
task copyJar(type:Copy){
from configurations.runtime
into ('build/libs/lib')
}
task release(type: Copy,dependsOn: [build,copyJar]) {
// from 'conf'
// into ('build/libs/eachend/conf')
}
建立函式copyJar 用於把依賴的jar複製到對應的目錄下。
函式release即是我們打包的時候的執行的函式,dependsOn[build,copyJar]這裡會讓執行relese函式的時候先執行build(系統自帶的函式) 和copyJar
最後通過gradle release命令進行打包
打包成功!
目錄如下:
cmd下進入對應目錄執行 java -jar XXX.jar
執行成功!
build.gradle 完整原始碼:
apply plugin: 'java'
apply plugin: 'idea'
version = '1.0'
repositories {
mavenCentral()
}
project.ext {
springVersion = '4.0.4.RELEASE'
minaVersion = '2.0.13'
}
dependencies {
compile('com.alibaba:dubbo:2.4.9') {
exclude group: 'org.springframework', module: 'spring'
}
compile( "org.apache.zookeeper:zookeeper:3.3.6") {
exclude group: 'javax.jms', module: 'jms'
exclude group: 'com.sun.jmx', module: 'jmxri'
exclude group: 'com.sun.jdmk', module: 'jmxtools'
}
compile( "com.github.sgroschupf:zkclient:0.1") {
exclude group: 'javax.jms', module: 'jms'
exclude group: 'com.sun.jmx', module: 'jmxri'
exclude group: 'com.sun.jdmk', module: 'jmxtools'
}
compile "org.springframework:spring-webmvc:$springVersion",
"org.springframework:spring-web:$springVersion",
"org.springframework:spring-tx:$springVersion",
"org.springframework:spring-orm:$springVersion",
"org.springframework:spring-jdbc:$springVersion",
"org.springframework:spring-expression:$springVersion",
"org.springframework:spring-core:$springVersion",
"org.springframework:spring-context:$springVersion",
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-aop:$springVersion",
"org.apache.mina:mina-http:$minaVersion",
"org.apache.mina:mina-core:$minaVersion",
"org.hibernate.common:hibernate-commons-annotations:4.0.1.Final",
"org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final",
"org.hibernate:hibernate-core:4.1.0.Final",
"com.alibaba:fastjson:1.1.33.android",
"com.google.code.gson:gson:2.2.4",
"org.jboss.netty:netty:3.2.5.Final",
"mysql:mysql-connector-java:5.1.10",
// "org.apache.zookeeper:zookeeper:3.3.6",
// "com.github.sgroschupf:zkclient:0.1",
"cn.jpush.api:jpush-client:3.2.9",
"redis.clients:jedis:2.6.1",
"javax.servlet:javax.servlet-api:3.1.0",
"net.sf.ezmorph:ezmorph:1.0.4",
"com.google.collections:google-collections:1.0",
"org.json:json:20090211",
"net.sf.json-lib:json-lib:2.2.1:jdk15",
fileTree(dir: 'lib', include: '*.jar')
}
jar {
String someString = ''
configurations.runtime.each {someString = someString + " lib\\"+it.name}
manifest {
attributes 'Main-Class': 'com.each.dubboMainEnd'
attributes 'Class-Path': someString
}
}
//清除上次的編譯過的檔案
task clearPj(type:Delete){
delete 'build','target'
}
task copyJar(type:Copy){
from configurations.runtime
into ('build/libs/lib')
}
//把JAR複製到目標目錄
task release(type: Copy,dependsOn: [build,copyJar]) {
// from 'conf'
// into ('build/libs/eachend/conf') // 目標位置
}
總結:
通過這個需求,我學到了很多:gradle的基礎語法,jar包是怎麼執行的,打包jar等,有事走些彎路並不是壞事,這會讓你把你自己的不足的知識學到。說說這打包,個人推薦第二種兩種方式,對於不怎麼了解gradle的同學們可以試試第一種。