S-JIS[2013-11-01/2021-12-19] 変更履歴

Gradle Javaプラグイン

Gradleでは、JavaプラグインでJavaソースをビルド(コンパイル)してjarファイルを生成することが出来る。

 

最小限の例

Javaのコンパイルを行う最小限の例。
build.gradleにJavaプラグインの宣言を追加するだけ。

build.gradle:

apply plugin: 'java'

実行方法

> gradle build
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 3.524 secs

gradleコマンドにbuildタスクを指定して実行する。
すると、Javaソースのコンパイルやjarファイルの生成および単体テストの実行が行われる。

「gradle jar」のようにjarタスクを指定すると、jarファイルの生成までが行われる。

「UP-TO-DATE」と表示されているタスクは、処理する内容が無かったことを意味する。


GradleのJavaプラグインでは、特に指定しない場合は以下のようなディレクトリー構成を想定している。
Mavenの構成とそっくり)

ビルドを実行すると、プロジェクトディレクトリーの下に以下のようなディレクトリーが作られる。

生成されるjarファイル名は、デフォルトでは「プロジェクトディレクトリー名.jar」となる。


Javaバージョン

コンパイル対象バージョン(javacコマンドの-source/-target相当)は以下の様に指定する。

build.gradle:

apply plugin: 'java'

sourceCompatibility = 1.6
targetCompatibility = 1.6

ソースファイルのエンコーディング

Javaのソースファイルのエンコーディングは以下の様にして指定する。

apply plugin: 'java'

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

compileJavaとcompileTestJavaはコンパイルを行うタスクなので、そのオプションのencodingを設定しているのだと思われる。

参考: NTTソフトウェアのJavaプロジェクトクイックスタート


あるいは、以下のように指定することも出来るらしい。

apply plugin: 'java'

tasks.withType(Compile){ options.encoding = 'UTF-8' }

参考: 倭マンさんのGradle ビルドファイル 〜エンコーディングも指定するヨ〜


Eclipseの設定のエンコーディングを指定する方法


依存ライブラリー

依存ライブラリー(使用するjarファイル)はdependenciesで指定する。

dependenciesブロック内に、どのタスクでそのライブラリーを使うのかを指定する。
主に「compile」「testCompile」「runtime」を指定することになるだろう。

apply plugin: 'java'

dependencies {
  compile     ライブラリーの指定
  testCompile ライブラリーの指定
  runtime     ライブラリーの指定
}

複数のライブラリーを指定する場合は、各行をいっぱい作るか、括弧を付けてその中に複数指定する。

dependencies {
  compile ライブラリー1
  compile ライブラリー2
  compile ライブラリー3
}
dependencies {
  compile(
    ライブラリー1,
    ライブラリー2,
    ライブラリー3, //末尾がカンマで終わっていても大丈夫
  )
}

依存ライブラリーのjarファイルを出力する方法


ライブラリー(jarファイル)の指定方法は、外部モジュール(Mavenのアーティファクト)を指定する方法や、ローカルファイルを指定する方法等がある。

外部モジュールの指定

Mavenのアーティファクトは、グループ名・アーティファクト名・バージョンの組で指定する。
指定方法には文字列記法とマップ記法の2種類がある。

記法 備考
文字列記法 'junit:junit:4.11'  
マップ記法 group: 'junit', name: 'junit', version: '4.11'  
[group: 'junit', name: 'junit', version: '4.11'] 例えば「compile()」の中に複数のライブラリーを書くときはカンマ区切りになるので、
各ライブラリーをマップ記法で書くなら[]を付けないといけない。

バージョンは「4.+」のように動的バージョンを指定することも出来る。この場合、リポジトリー内の最新バージョンが使われる。

repositories {
  mavenCentral()
}

dependencies {
  testCompile 'junit:junit:4.+'
}

Mavenリポジトリーの指定方法

ローカルファイルの指定

ローカルファイルを個別に指定する場合はfilesを使う。カンマ区切りで複数指定可能。

dependencies {
  compile files('libs/a.jar', 'libs/b.jar')
}

ディレクトリー内にあるファイルを指定するにはfileTreeを使う。

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

別プロジェクトの指定

別のプロジェクトを指定する場合はprojectを使う。

dependencies {
  compile project(':shared')
}

生成されるjarファイルの名前

デフォルトでは、生成されるjarファイル名はプロジェクト名(プロジェクトのディレクトリー名)と同じになる。

ビルドスクリプト内でversionを指定すると、生成されるjarファイルにバージョンが付く。
また、jar.baseNameやarchivesBaseNameでjarファイル名を指定することも出来る。

指定内容
プロジェクト名 ビルドスクリプト内の指定 生成されるjarファイルの名前
指定なし java-example なし java-example.jar
バージョンのみ java-example version = '0.1-SNAPSHOT' java-example-0.1-SNAPSHOT.jar
baseNameのみ java-example jar.baseName = 'zzz' zzz.jar
baseNameとバージョン java-example jar.baseName = 'zzz'
version = '0.1-SNAPSHOT'
zzz-0.1-SNAPSHOT.jar
archivesBaseNameとバージョン java-example archivesBaseName = 'zzz'
version = '0.1-SNAPSHOT'
zzz-0.1-SNAPSHOT.jar

Mavenリポジトリーへの登録


MANIFEST.MF

生成されるjarファイル内のマニフェストファイル(MANIFEST.MF)の属性を指定するには、jar.manifest.attributesに値をセットする。

build.gradle:

apply plugin: 'java'

jar {
  manifest.attributes 'Main-Class': 'org.example.Main'
  from configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
}
apply plugin: 'java'

version = '0.1-SNAPSHOT'

jar {
  manifest {
    attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
  }
}

'キー': '値'」の形式をカンマ区切りで複数指定できる。


リソースファイル

生成されるjarファイル内に(MANIFEST.MF以外の)ファイルを入れるには、src/main/resourcesにファイルを置いておく。 [2015-05-17]

例えばjarファイル内に「META-INF/services/com.example.Spi」というファイルを入れたい場合、以下のような配置でファイルを用意しておくと、jarファイル生成時に自動的に含めてくれる。

参考: stackoverflowのMETA-INF/services in JAR with Gradle


ソースセット

デフォルトのソースセット(src/main/java, src/main/resources, src/test/java等)以外のソースセットを作ることが出来る。[2015-12-28]

例えばサンプルソースを置く為のsrc/example/javaを作りたい場合、以下のようにする。

build.gradle:

sourceSets {
    example {
        java {
            srcDir 'src/example/java'
        }
    }
}
〜

これでEclipseプロジェクトを作ると、src/example/javaもソースディレクトリーとして認識される。

compileJavaタスクを実行した場合は(src/mainが対象なので)src/example/javaは含まれない。


jarファイルにソースファイルを含める

ビルドして作られたjarファイルには、classファイル(とリソースファイル)しか入っていない。[2021-12-19]
ちょっとファイルサイズは大きくなるが、ソース(javaファイル)も含まれている方がデバッグには便利。

jarファイルにソースファイルを含めるには、jarタスクに処理を追加する。

build.gradle:

jar {
    from ('./src/main/java') {
        include '**/*.java'
    }
}
〜

依存ライブラリーの出力

依存ライブラリー(dependencies)のjarファイルをまとめて出力することが出来る。[2013-11-06]

build.gradle:

apply plugin: 'java'
〜

dependencies {
  compile 'commons-cli:commons-cli:1.2'
}

// ライブラリーをコピーするタスク
task copyLib(type: Copy){
  from configurations.compile
  into 'build/lib'
}

この例では、dependencies(configurations)の「compile」で指定したライブラリーのjarファイルを「build/lib」の下にコピーする。
そのライブラリーがさらに別のライブラリーに依存している場合は、それも一緒にコピーされる。

実行例

実行する際にライブラリーコピー用のタスクを指定する。

> gradle copyLib
:copyLib

BUILD SUCCESSFUL

Total time: 9.747 secs

> dir /b build\lib
commons-cli-1.2.jar

参考: dev-xconnectingさんのGradleで外部依存関係に指定したjarファイルをプロジェクト内のディレクトリにコピーする


マルチプロジェクト

依存関係のある複数プロジェクトを扱うには、マルチプロジェクトの設定を行う。[2015-12-28]

例えばcoreプロジェクトとそれを参照するsubプロジェクトがある場合、rootディレクトリーを作り、その下にcoreとsubのプロジェクトを置く。
そして、rootに共通のbuild.gradleを置き、差分だけcoreとsubのbuild.gradleに記述する。
また、rootにはsettings.gradleを置き、プロジェクト一覧を記述する。

なお、プロジェクトのディレクトリー名がアーティファクトIDになるので、そのつもりで命名する必要がある。
rootのbuild.graldeのgroupを「com.example」とした場合、coreプロジェクトから生成されるpom.xmlは「<groupId>com.example</groupId> <artifactId>core</artifactId>」になる)

root/settings.java

include "core", "sub"

root/build.gradle

subprojects {
    apply plugin: 'java'
    apply plugin: 'eclipse'
    apply plugin: 'maven'
    apply plugin: 'maven-publish'

    defaultTasks 'jar'

    group = 'com.example'
    version = '0.1.0'

    sourceCompatibility = 1.6
    targetCompatibility = 1.6

    def defaultEncoding = 'UTF-8'
    [compileJava, compileTestJava]*.options*.encoding = defaultEncoding

    repositories {
        mavenCentral()
        maven { url 'http://hishidama.github.io/mvnrepository' }
    }

    dependencies {
        testCompile 'junit:junit:4.12'
    }

    task wrapper(type: Wrapper) {
        gradleVersion '2.8'
        jarFile file('.buildtools/gradlew.jar')
    }

    eclipse.classpath.file {
        whenMerged { classpath ->
            classpath.entries.findAll { entry -> entry.kind == 'output' }*.path = 'classes'
        }
    }

    // publish
    task sourceJar(type: Jar) {
        from sourceSets.main.allJava
    }

    publishing {
        publications {
            mavenJava(MavenPublication) {
                from components.java

                artifact sourceJar {
                    classifier "sources"
                }
            }
        }
        repositories {
            maven {
                url "$buildDir/../../mvnrepository"
            }
        }
    }
}

共通のbuild.gradleでは、各プロジェクトに共通の設定を、subprojectsブロック内に記述する。

root/core/build.gradle

dependencies {
    compile 'hoge:fuga:0.1'
}

root/sub/build.gradle

dependencies {
    compile project(':core')
    compile 'foo:bar:0.1'
}

依存するプロジェクトは、「compile project(':依存プロジェクト名')」で指定する。


このrootディレクトリーの下でgradleコマンドを実行すると、配下のプロジェクト全てに対してタスクが実行される。

$ cd root
$ gradle wrapper
:wrapper
:core:wrapper
:sub:wrapper

BUILD SUCCESSFUL

Total time: 4.003 secs
$ ./gradlew cleanEclipse eclipse
:core:cleanEclipseClasspath UP-TO-DATE
:core:cleanEclipseJdt UP-TO-DATE
:core:cleanEclipseProject UP-TO-DATE
:core:cleanEclipse UP-TO-DATE
:sub:cleanEclipseClasspath UP-TO-DATE
:sub:cleanEclipseJdt UP-TO-DATE
:sub:cleanEclipseProject UP-TO-DATE
:sub:cleanEclipse UP-TO-DATE
:core:eclipseClasspath
:core:eclipseJdt
:core:eclipseProject
:core:eclipse
:sub:eclipseClasspath
:sub:eclipseJdt
:sub:eclipseProject
:sub:eclipse

BUILD SUCCESSFUL

Total time: 7.719 secs
$ ./gradlew jar
:core:compileJava UP-TO-DATE
:core:processResources UP-TO-DATE
:core:classes UP-TO-DATE
:core:jar
:sub:compileJava UP-TO-DATE
:sub:processResources UP-TO-DATE
:sub:classes UP-TO-DATE
:sub:jar

BUILD SUCCESSFUL

Total time: 2.916 secs

jar(compileJava)タスクのようにプロジェクトの依存があるタスクでは、依存の順序に従って実行される。


$ ./gradlew publish
:core:generatePomFileForMavenJavaPublication
:core:compileJava UP-TO-DATE
:core:processResources UP-TO-DATE
:core:classes UP-TO-DATE
:core:jar UP-TO-DATE
:core:sourceJar UP-TO-DATE
:core:publishMavenJavaPublicationToMavenRepositoryCould not find metadata com.example:core/maven-metadata.xml in remote (file:/tmp/gradle-example/root/mvnrepository)

:core:publish
:sub:generatePomFileForMavenJavaPublication
:sub:compileJava UP-TO-DATE
:sub:processResources UP-TO-DATE
:sub:classes UP-TO-DATE
:sub:jar UP-TO-DATE
:sub:sourceJar UP-TO-DATE
:sub:publishMavenJavaPublicationToMavenRepositoryCould not find metadata com.example:sub/maven-metadata.xml in remote (file:/tmp/gradle-example/root/mvnrepository/)

:sub:publish

BUILD SUCCESSFUL

Total time: 3.341 secs

$ ls mvnrepository/com/example/
core  sub

この例では、publishの出力先を「$buildDir/../../mvnrepository」にしてある。
$buildDirは各プロジェクトのbuildディレクトリー(root/core/buildやroot/sub/build)なので、「$buildDir/../../mvnrepository」はroot/mvnrepositoryになる。


個別のプロジェクトに対してgradleコマンドを実行したい場合は、各プロジェクトディレクトリーに移動してコマンドを実行するか、タスクにプロジェクト名を指定して実行する。

$ cd root/core
$ ./gradlew jar
$ cd root
$ ./gradlew core:jar

Gradle目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま