網頁

2020/4/27

IntelliJ IDEA Gradle 打包可執行的jar檔 build executable jar

IntelliJ IDEA Gradle打包可執行的jar檔方式如下:


注意本篇打包的是簡單的Java應用程式,而非Web應用程式或Spring Boot專案。


範例環境:

  • Mac OS
  • IntelliJ IDEA 2019.2.1 (Community Edition)
  • Java 8
  • Gradle

在IntelliJ IDEA建立一個簡單的Java Gradle專案。build.gradle內容如下,裡面加了些依賴如專案內libs目錄下的jar,Apache commons 等jar。

build.gradle

plugins {
    id 'java'
}

group 'com.abc'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile fileTree(dir: "libs", include: '*.jar')

    compile group: 'org.apache.commons', name: 'commons-text', version: '1.8'
    compile group: 'commons-io', name: 'commons-io', version: '2.6'

    testCompile group: 'junit', name: 'junit', version: '4.12'
}
 

撰寫一個main方法類別App如下。

com.abc.app.App

package com.abc.app;

public class App {

    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

使用IntelliJ IDEA的Gradle -> Tasks -> build -> jar打包專案為jar檔。

本範例打包後的jar檔名為demo-1.0-SNAPSHOT.jar

在terminal執行demo-1.0-SNAPSHOT.jar時出現「找不到manifest attribute」的訊息而無法執行。

$ java -jar demo-1.0-SNAPSHOT.jar
no main manifest attribute, in demo-1.0-SNAPSHOT.jar 

問題在於可執行的jar中必須包含一份MANIFEST.MF文件,並以其中的Main-Class屬性指定main類別才能使用java -jar指令來執行。此外程式執行時會使用到依賴的jar,因此需把這些依賴jar一起打包成fat jar

解決方式是在build.gradle多設定以下,Main-Class為main類別的fully qualified name。

jar {
    // MANIFEST.MF指定main class
    manifest {
        attributes(
                'Main-Class': 'com.abc.app.App'
        )
    }

    // 打包成fatJar
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

修改後的build.gradle

build.gradle

plugins {
    id 'java'
}

jar {
    manifest {
        attributes(
                'Main-Class': 'com.abc.app.App'
        )
    }
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

group 'com.abc'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile fileTree(dir: "libs", include: '*.jar')

    compile group: 'org.apache.commons', name: 'commons-text', version: '1.8'
    compile group: 'commons-io', name: 'commons-io', version: '2.6'

    testCompile group: 'junit', name: 'junit', version: '4.12'
}

如此便能正確地執行了。

$ java -jar demo-1.0-SNAPSHOT.jar
hello world

沒有留言:

張貼留言