Gradleで実行可能なJARを作成する


147

これまでは、Eclipseの「エクスポート...」機能を使用して実行可能なJARファイルを作成していましたが、ビルドの自動化のためにIntelliJ IDEAとGradleに切り替えました。

ここのいくつかの記事は「アプリケーション」プラグインを提案していますが、これは私が期待した結果に完全につながるわけではありません(JARのみ、開始スクリプトなしなど)。

「エクスポート...」ダイアログでEclipseと同じ結果を得るにはどうすればよいですか?

回答:


164

実行可能なjarファイルは、マニフェストにMain-Classエントリを含むjarファイルです。したがって、このエントリをマニフェストに追加するには、jarタスクを構成するだけです。

jar {
    manifest {
        attributes 'Main-Class': 'com.foo.bar.MainClass'
    }
}

マニフェストにクラスパスエントリを追加する必要がある場合もありますが、これは同じ方法で行われます。

http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.htmlを参照してください


6
これは私が探していたもののようです。しかし、私はbuild.gradleで既に依存関係を宣言していますが、本当に手動でクラスパスを追加する必要がありますか、それとも依存関係宣言を再利用できますか?
Hannes

「ランタイム」構成内のライブラリをループし、それらを連結してClass-Path属性値を作成できる必要があります。
JBニゼット2014

3
「inseid「ランタイム」構成」とはどういう意味ですか?愚かな質問で申し訳ありませんが、私はGradleにかなり慣れていません...
Hannes

Gradle Javaプラグインは、4つの異なるクラスパスに対応する4つの「構成」を定義します。コンパイル(Javaファイルのコンパイルに使用)、testCompile(テストJavaソースファイルのコンパイルに使用)、ランタイム(アプリケーションの実行に使用)、およびtestRuntime(テストの実行に使用されます)。gradle.org/docs/current/userguide/…を
JB

ああ、ありがとう-正しく理解してJARを作成できたので、クラスパスの作成に悩んでいます;-)ご協力ありがとうございます。
ハネス14

97

JB NizetとJorge_Bの答えはどちらも正しいです。

最も単純な形式では、Gradleで実行可能JARを作成することは、マニフェストに適切なエントリを追加することだけです。ただし、クラスパスに含める必要のある依存関係を持つ方がはるかに一般的であるため、このアプローチは実際には扱いにくくなっています。

アプリケーションプラグインは別のアプローチを提供します。実行可能JARを作成する代わりに、以下を提供します。

  • runビルドから直接アプリケーションを簡単に実行できるようにするタスク
  • installDistビルドされたJAR、依存するすべてのJAR、および実行可能なプログラムにすべてをまとめる起動スクリプトを含むディレクトリ構造を生成するタスク
  • distZipおよびdistTar完全なアプリケーション配布を含むアーカイブを作成するタスク(起動スクリプトとJAR)

3番目の方法は、いわゆる「ファットJAR」を作成することです。これは、コンポーネントのコードだけでなく、そのすべての依存関係も含む実行可能JARです。このアプローチを使用するプラグインはいくつかあります。私が知っているいくつかへのリンクを含めました。まだまだあると思います。


シャドウと1瓶を試してみました。私は1つのjarに固執します。それはよりシンプルで使いやすいです。涼しい!ありがとう
Jako

残念ながらone-jarは、Gradleの最新バージョンでは機能しません。たとえば、github.com
rholder /

ここでのjarタスクを変更することによって、一瓶を構築するためのワンライナーソリューションです。これが最も便利だと思いました。configurations.runtime単一のjarにランタイム依存関係をバンドルするには、追加する必要があることに注意してください。
Quazi Irfan、

私は「アプリケーションプラグイン」が自分のニーズにふさわしく、十分に柔軟であることを発見しました。また、すべてを圧縮して圧縮し、そのzipに余分なファイルを含めたり除外したりすることもできます。また、カスタムタスクを使用して、エントリポイントを追加した別のランチャースクリプトを追加することもできます。
kinORnirvana

生成された.tar/ .zipファイルをどのように実行しますか?
トビック

35

他の人が指摘したように、jarファイルを実行可能にするには、アプリケーションのエントリポイントをMain-Classマニフェストファイルの属性に設定する必要があります。依存関係クラスファイルが併置されていない場合Class-Pathは、マニフェストファイルのエントリに設定する必要があります。

私はあらゆる種類のプラグインの組み合わせを試してみましたが、実行可能jarを作成するという単純なタスクではなく、どういうわけか、依存関係を含めました。すべてのプラグインが何らかの方法で不足しているように見えますが、ついに思い通りの結果になりました。不可解なスクリプトはなく、ビルドディレクトリを汚染する100万の異なるミニファイル、かなりクリーンなビルドスクリプトファイル、そして何よりも、100万の外部サードパーティクラスファイルが私のjarアーカイブにマージされていません。

以下は、ここからコピーして貼り付けたものです。

[方法]サブディレクトリに依存関係jarを含む配布zipファイルを作成し、/libすべての依存関係を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:
    //     /programming/22659463/add-classpath-in-manifest-using-gradle
    //     https://gist.github.com/simon04/6865179
}

ここで要旨としてホストされています

結果はにbuild/distributionsあり、解凍されたコンテンツは次のようになります。

lib / commons-lang3-3.3.2.jar
MyJarFile.jar

の内容MyJarFile.jar#META-INF/MANIFEST.mf

Manifest-Version:1.0
Main-Class:com.somepackage.MainClass
Class-Path:lib / commons-lang3-3.3.2.jar


現在のアプリケーションjarもディストリビューションの「lib」ディレクトリにあります。をトップディレクトリに移動するか、次の行を変更する必要があります。 'Class-Path':configuration.runtime.files.collect {"$ it.name"} .join( '')}
Marc Nuri

1
@MarcNuriよろしいですか?私は自分のアプリケーションのために、このアプローチを使用してみました、そして現在のアプリケーションジャーだっないlib生産さのzip / tarファイルのディレクトリではなく、中にいたlibこの答えが示すように、の親ディレクトリ。この解決策は私には申し分なく機能したようです。
thejonwithnoh

1
@thejonwithnohごめんなさい、あなたは正しいです。「java-library-distribution」プラグインを使用するために提案されたソリューションが見つかりませんでした。私の場合、すべてのjarファイル(アプリケーションjar を含む)が「lib」ディレクトリにあるという主な違いはありますが、同じ作業を行う「アプリケーション」プラグインを使用しています。したがって、に変更"lib/$it.name"する"$it.name"と仕事ができます。
Marc Nuri

28

私にとって最も簡単な解決策は、gradle-shadow-pluginを利用することでした

プラグインを適用する以外に、実行する必要があるのは次のとおりです。

Mainクラスをマニフェストに入れるようにjarタスクを構成します

jar {
  manifest {
   attributes 'Main-Class': 'com.my.app.Main'
  }
}

Gradleタスクを実行する

./gradlew shadowJar

テイクアプリバージョン-all.jarをからビルドを/ libsに/

そして最後にそれを実行します:

java -jar app-version-all.jar

2
これが完全なbuild.gradleです。
Brad Turek

このビルドを実行すると、BUILD SUCCESSFULが表示されますが、java -jar build / libs / core-all-1.0.jarを使用してjarファイルを実行しようとすると、次のエラーが発生します。 Mainが原因:java.lang.ClassNotFoundException:scanners.exchange.Mainこれを解決する方法を知っていますか?
Luka Lopusina

@LukaLopusina指定したクラスはJARファイルにありません。kotlinを使用している場合は、と言う必要があります'com.my.app.MainKt'。これ以上の情報がなければ、私はあなたをさらに助けることはできません。
byxor

現在のプラグインShadow v5。+は、Gradle 5.0+およびJava 7+とのみ互換性があります。
Zon

5

「installApp」タスクを試しましたか?起動スクリプトのセットで完全なディレクトリを作成しませんか?

http://www.gradle.org/docs/current/userguide/application_plugin.html


私が理解していることからinstallAppMETA-INF/MANIFEST.MFファイルを作成しません。私は何か間違ったことをしていますか?
2014年

1
アプリケーションプラグインのinstallAppタスクリストにタスクが表示されません。もしかして代わりに?installDist
Quazi Irfan、

2
はい、Gradle 3.0 でinstallAppに名前が変更されinstallDistました。こちらがリリースノートです。
Quazi Irfan、

4

コンスタンティン、ありがとうございます。ニュアンスの少ない魅力的な作品でした。何らかの理由で、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- {version} -all.jarを取得します。これは、java -jar myapp- {version} -all.jarとして実行できます。


3

モジュール設定(またはプロジェクト構造)でjarアーティファクトを定義できます。

  • モジュールを右クリック>モジュール設定を開く>アーティファクト> +> JAR>依存関係を持つモジュールから。
  • メインクラスを設定します。

jarの作成は、[ビルド]メニューの[ビルドアーティファクト...]をクリックするのと同じくらい簡単です。おまけとして、すべての依存関係を1つのjarファイルにパッケージ化できます。

IntelliJ IDEA 14 Ultimateでテスト済み。


2

私は解決策のかなりの数のリンクをチェックし、最終的にそれを機能させるために下記の手順を実行しました。Gradle 2.9を使用しています。

build、gradleファイルに次の変更を加えます。

  1. メンションプラグイン:

    apply plugin: 'eu.appsatori.fatjar'
  2. Buildscriptを提供します。

    buildscript {
    repositories {
        jcenter()
    }
    
    dependencies {
        classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
    }
    }
  3. メインクラスを提供します。

    fatJar {
      classifier 'fat'
      manifest {
        attributes 'Main-Class': 'my.project.core.MyMainClass'
      }
      exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
    }
  4. fatjarを作成します。

    ./gradlew clean fatjar
  5. / build / libs /からfatjarを実行します。

    java -jar MyFatJar.jar

1
2019年以降:この提案はここでは機能しません。依存関係はfatjarに含まれていません
carl

1

SpringBootプラグインを使用できます。

plugins {
  id "org.springframework.boot" version "2.2.2.RELEASE"
}

瓶を作る

gradle assemble

そしてそれを実行します

java -jar build/libs/*.jar

注:このプラグインを使用するためにプロジェクトがSpringBootプロジェクトである必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.