到現在爲止,我通過Eclipse的「Export ...」功能創建了可運行的JAR文件,但現在我切換到了IntelliJ IDEA和Gradle以實現構建自動化。一些文章提出了「應用程序」插件,但這並不完全導致我期望的結果(只是一個JAR,沒有啓動腳本或類似的東西)。使用Gradle創建可運行的JAR
如何才能達到Eclipse使用「導出...」對話框所做的相同結果?
到現在爲止,我通過Eclipse的「Export ...」功能創建了可運行的JAR文件,但現在我切換到了IntelliJ IDEA和Gradle以實現構建自動化。一些文章提出了「應用程序」插件,但這並不完全導致我期望的結果(只是一個JAR,沒有啓動腳本或類似的東西)。使用Gradle創建可運行的JAR
如何才能達到Eclipse使用「導出...」對話框所做的相同結果?
可執行的JAR文件只是包含在其清單一個主級條目的jar文件。所以,你只需要以在其清單添加此項配置jar task:
jar {
manifest {
attributes 'Main-Class': 'com.foo.bar.MainClass'
}
}
您可能還需要在清單中添加類路徑條目,但會做同樣的方式。
見http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
您是否嘗試過'installApp'任務?它不是用一組啓動腳本創建完整目錄嗎?
據我瞭解,'installApp'不創建'META-INF/MANIFEST.MF'文件。難道我做錯了什麼? – advait
兩個JB Nizet和Jorge_B的答案是正確的。
以最簡單的形式,使用Gradle創建可執行JAR只是將適當的條目添加到manifest。然而,需要在類路徑中包含依賴關係更爲常見,這使得這種方法在實踐中變得棘手。
application plugin提供了一種替代方法;而不是創建一個可執行的JAR,它提供了:
run
任務,以便輕鬆地直接從構建installDist
任務產生包括內置JAR的目錄結構運行的應用程序,所有的JAR文件的這這取決於,而且拉它連成一個程序的啓動腳本,你可以運行創建一個包含一個完整的應用程序分發歸檔(啓動腳本和JAR)distZip
和distTar
任務第三種方法是創建一個所謂的「胖JAR」,它是一個可執行JAR,它不僅包含組件的代碼,還包含其所有依賴項。有幾種不同的插件使用這種方法。我已經包含了一些我知道的鏈接;我相信還有更多。
只是試過陰影和一個罐子。我會堅持一個jar:它更簡單,更易於使用。涼!謝謝 – Jako
您可以定義模塊設置(或項目結構)的罐子神器。
製作一個jar就像在Build菜單中點擊「Build artifact ...」一樣簡單。作爲獎勵,您可以將所有依賴關係打包到一個jar中。
經過IntelliJ IDEA 14 Ultimate測試。
正如其他人已經注意到的,爲了使jar文件可執行,必須在清單文件的Main-Class
屬性中設置應用程序的入口點。如果依賴關係類文件不搭配,則需要在清單文件的Class-Path
條目中設置它們。
我已經嘗試過各種插件組合,並且對於創建可執行jar以及某種方式的簡單任務來說,還包括依賴關係。所有插件似乎都缺乏這種或那種,但最終我得到了它,就像我想要的。沒有神祕的腳本,沒有百萬個不同的迷你文件污染了構建目錄,一個非常乾淨的構建腳本文件,最重要的是:沒有一百萬個外國第三方類文件合併到我的jar文件中。
下面是here爲了您的方便複製粘貼..
[操作指南]在子目錄/lib
創建依賴罐子分佈zip文件,所有的依賴關係添加到清單Class-Path
進入文件:
apply plugin: 'java'
apply plugin: 'java-library-distribution'
repositories {
mavenCentral()
}
dependencies {
compile 'org.apache.commons:commons-lang3:3.3.2'
}
// Task "distZip" added by plugin "java-library-distribution":
distZip.shouldRunAfter(build)
jar {
// Keep jar clean:
exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'
manifest {
attributes 'Main-Class': 'com.somepackage.MainClass',
'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
}
// How-to add class path:
// https://stackoverflow.com/questions/22659463/add-classpath-in-manifest-using-gradle
// https://gist.github.com/simon04/6865179
}
作爲要點主辦here。
結果可以在build/distributions
發現並解壓縮後的內容是這樣的:
的lib /公地lang3-3.3.2.jar
myJarFile.jar中
內容的MyJarFile.jar#META-INF/MANIFEST.mf
:
Manifest-Version:1.0
主類:com.somepackage.MainClass
類路徑:LIB /公地lang3-3.3.2.jar
我
當前的應用程序jar也將位於發行版的'lib'目錄中。您必須將其移動到頂部目錄或更改此行: 'Class-Path':configurations.runtime.files.collect {「lib/$ it.name」} .join('') } 對此: 'Class-Path':configurations.runtime.files.collect {「$ it.name」} .join('') } –
@MarcNuri Are you sure?我嘗試在我的應用程序中使用這種方法,當前的應用程序jar在生成的zip/tar文件的'lib'目錄中是** not **,而是在'lib'的父目錄中,正如這個答案所暗示的。這個解決方案似乎對我來說非常合適。 – thejonwithnoh
@thejonwithnoh對不起,你是對的。我沒有看到提出使用「java-library-distribution」插件的解決方案。就我而言,我只是簡單地使用「應用程序」插件來完成相同的工作,主要區別在於所有的jar文件(**包括應用程序jar)都位於「lib」目錄中。因此,將''lib/$ it.name'''改爲''$ it.name'''即可完成這項工作。 –
最省力的解決辦法是使用的gradle-shadow-plugin
除了應用插件,所有需要做的是:
配置jar任務把主類成清單
jar { manifest { attributes'Main-Class':'com.my.app。主 }}
運行gradle這個任務./gradlew shadowJar
採取應用程序版本,all.jar在從編譯/庫/
最後通過執行它:
java -jar app-version-all.jar
這是[完整的'build.gradle'示例](https://gist.github.com/TurekBot/4a3cd406cb52dfd8bfb8022b982f0f6c)。 –
謝謝康斯坦丁,它的工作方式像一個幾乎沒有細微差別的魅力。出於某種原因,將main類指定爲jar清單的一部分並不完美,它需要改爲mainClassName屬性。下面是從的build.gradle片段,包括一切,使其工作:
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '1.2.2'
}
...
...
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
...
...
mainClassName = 'com.acme.myapp.MyClassMain'
...
...
...
shadowJar {
baseName = 'myapp'
}
運行gradle這個shadowJar後你會得到myapp- {}版本在-all.jar你的build文件夾可以作爲運行Java的罐子myapp- {}版本-all.jar。
我檢查了相當一些解決方案的鏈接,最後做了下面提到的步驟來讓它工作。我正在使用Gradle 2.9。
讓你構建了以下變化,gradle這個文件:
提到插件:
apply plugin: 'eu.appsatori.fatjar'
提供的Buildscript:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
提供主要類別:
fatJar {
classifier 'fat'
manifest {
attributes 'Main-Class': 'my.project.core.MyMainClass'
}
exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
}
創建fatjar:
./gradlew clean fatjar
運行從fatjar /建設/庫/:
java -jar MyFatJar.jar
這似乎是我正在尋找;但是:我已經在build.gradle中聲明瞭依賴關係,是否真的必須手動添加類路徑,還是可以重新使用我的依賴關係聲明? – Hannes
您應該能夠遍歷'runtime'配置中的庫,並將它們連接起來以創建Class-Path屬性值。 –
「inseid」運行時配置是什麼意思?對於愚蠢的問題抱歉,我對Gradle相當陌生... – Hannes