[java] Gradle을 사용하여 실행 가능한 JAR 작성

지금까지 Eclipse “Export …”기능을 통해 실행 가능한 JAR 파일을 작성했지만 빌드 자동화를 위해 IntelliJ IDEA 및 Gradle로 전환했습니다.

여기의 일부 기사는 “application”플러그인을 제안하지만, 이것이 내가 예상 한 결과를 초래하지는 않습니다 (JAR, 시작 스크립트 또는 이와 유사한 것).

“내보내기 …”대화창에서 Eclipse와 동일한 결과를 얻는 방법은 무엇입니까?



답변

실행 가능한 jar 파일은 매니페스트에 Main-Class 항목을 포함하는 jar 파일 일뿐입니다. 따라서이 항목을 매니페스트에 추가 하려면 jar 작업 만 구성하면됩니다 .

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

매니페스트에 클래스 경로 항목을 추가해야 할 수도 있지만 동일한 방식으로 수행됩니다.

http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html을 참조 하십시오.


답변

JB Nizet와 Jorge_B의 답변이 모두 맞습니다.

가장 간단한 형태로 Gradle을 사용하여 실행 가능한 JAR을 작성하는 것은 매니페스트에 적절한 항목을 추가하는 입니다. 그러나 클래스 경로에 포함되어야하는 종속성을 갖는 것이 훨씬 일반적이므로이 방법은 실제로 까다로워집니다.

애플리케이션 플러그인은 다른 접근 방법을 제공합니다; 실행 가능한 JAR을 작성하는 대신 다음을 제공합니다.

  • run빌드에서 직접 응용 프로그램을 쉽게 실행할 수 있는 작업
  • installDist빌드 된 JAR, 여기에 종속 된 모든 JAR 및이를 실행할 수있는 프로그램으로 모두 가져 오는 시작 스크립트를 포함하여 디렉토리 구조를 생성 하는 태스크
  • distZip그리고 distTar완전한 응용 프로그램 배포를 포함하는 아카이브 (시작 스크립트와 JAR 파일)을 생성 작업

세 번째 방법은 구성 요소의 코드뿐만 아니라 모든 종속성을 포함하는 실행 가능한 JAR 인 소위 “팻 JAR”을 만드는 것입니다. 이 방법을 사용하는 몇 가지 다른 플러그인이 있습니다. 내가 아는 몇 가지에 대한 링크를 포함 시켰습니다. 나는 더 많은 것이 확신합니다.


답변

다른 사람들이 지적했듯이 jar 파일을 실행하려면 응용 프로그램의 진입 점이 Main-Class매니페스트 파일 의 속성 에서 설정되어야 합니다. 종속성 클래스 파일이 배치되지 않은 Class-Path경우 매니페스트 파일 의 항목 에서 설정해야 합니다.

나는 모든 종류의 플러그인 조합을 시도했으며 실행 가능한 jar를 만드는 간단한 작업과 어쨌든 의존성을 포함하지 않았습니다. 모든 플러그인에는 어떤 식 으로든 부족한 것처럼 보이지만 마침내 원하는대로 얻었습니다. 빌드 디렉토리를 오염시키는 수백만 개의 미니 파일이 아니라 매우 깨끗한 빌드 스크립트 파일이 아니라 신비한 스크립트가 없습니다.

다음은 귀하의 편의를 위해 여기 에서 복사하여 붙여 넣기입니다 .

[방법] 하위 디렉토리에 종속 jar을 포함하는 배포 zip 파일을 작성하고 /lib모든 종속 Class-Path항목을 Manifest 파일의 항목에 추가 하십시오.

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:

매니페스트 버전 : 1.0
기본 클래스 : com.somepackage.MainClass
클래스 경로 : lib / commons-lang3-3.3.2.jar


답변

나를위한 최소한의 노력 솔루션은 gradle-shadow-plugin 을 사용하는 것이 었습니다

플러그인을 적용하는 것 외에도 다음을 수행해야합니다.

메인 클래스를 매니페스트에 넣도록 jar 작업을 구성하십시오.

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

gradle 작업을 실행하십시오.

./gradlew shadowJar

build / libs / 에서 app-version-all.jar 을 가져옵니다.

마지막으로 다음을 통해 실행하십시오.

java -jar app-version-all.jar


답변

‘installApp’태스크를 시도 했습니까? 시작 스크립트 세트로 전체 디렉토리를 작성하지 않습니까?

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


답변

Konstantin에게 감사합니다. 미묘한 차이가 거의 없었습니다. 어떤 이유로 든 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로 실행할 수 있습니다.


답변

모듈 설정 (또는 프로젝트 구조)에서 jar 이슈를 정의 할 수 있습니다.

  • 종속성이있는 모듈에서 모듈> 모듈 설정 열기> 아티팩트> +> JAR>을 마우스 오른쪽 단추로 클릭하십시오.
  • 메인 클래스를 설정하십시오.

그런 다음 빌드 메뉴에서 “빌드 아티팩트 …”를 클릭하는 것만 큼 쉽게 항아리를 만들 수 있습니다. 보너스로 모든 의존성을 단일 jar로 패키징 할 수 있습니다.

IntelliJ IDEA 14 Ultimate에서 테스트되었습니다.