日記マン

モチベはGCP, MapReduce, MachineLearning, Docker, [Kotlin/Go/Python] です。アカデミックへの興味は情報幾何や計算論的神経科学など。

ビルドツールをGradleに乗り換えた (Kotlinによる開発, 外部依存jarの生成方法も記載)

Apache Beam (Cloud Dataflow)をJava SDKで開発している。(さらにいうと言語はKotlinで開発)
ビルドツールにMavenを利用していたが、Gradleに乗り換えた。

ディレクトリ構成はこう。

.
├── README.md
├── src
│   ├── main
│   └── test
└── build.gradle

build.gradle ファイル

apply plugin: 'java'
apply plugin: 'application'

repositories {
    mavenCentral()
}

group = 'com.github.kazukousen'
version = '1'
sourceCompatibility = 1.8

dependencies {
    testCompile 'junit:junit:4.12'

    /* start Apache Beam */
    compile "org.apache.beam:beam-runners-google-cloud-dataflow-java:2.4.0"
    compile "org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.4.0"
    testCompile "org.hamcrest:hamcrest-all:1.3"
    /* end Apache Beam */
}

mainClassName = "com.github.kazukousen.myproject.Hello"
run {
    if (project.hasProperty('args')) {
        args project.args.split('\\s')
    }
}

ポイントは、task run をargsが空白で区切られるように拡張する。
これにより、実行時の引数オプションは、

gradle run -Pargs="--hoge=fuga --foo=bar"

というふうに渡して実行する。

Kotlin用

個人的にJavaではなくKotlinでかきたいため、Kotlin用に build.gradle を書き換えている。

buildscript {
    ext.kotlin_version = '1.2.31'
    ext.beam_version = '2.4.0'
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

apply plugin: 'kotlin'
apply plugin: 'application'

repositories {
    mavenCentral()
}

group = 'com.github.kazukousen'
version = '1'
sourceCompatibility = 1.8

dependencies {
    /* start Kotlin */
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
    /* end Kotlin */
    testCompile 'junit:junit:4.12'

    /* start Apache Beam */
    compile "org.apache.beam:beam-runners-google-cloud-dataflow-java:$beam_version"
    compile "org.apache.beam:beam-sdks-java-io-google-cloud-platform:$beam_version"
    testCompile "org.hamcrest:hamcrest-all:1.3"
    /* end Apache Beam */
}

mainClassName = "com.github.kazukousen.myproject.HelloKt"
run {
    if (project.hasProperty('args')) {
        args project.args.split('\\s')
    }
}

スタンドアロンjarの生成

Cloud Dataflowには関係のない話だが、
mavenでいう with-dependencies なjarを生成するには、

jar {
    manifest {
        attributes "Main-Class" : "com.github.kazukousen.myproject.HelloKt"
    }
    from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}

こんなふうに task jar を拡張する。

gradle build

build/libs/ に全ての依存モジュールを含んだスダンドアロンjarファイルが生成される。

まとめ

ビルドツールは他にMavenがあり、Apache Beamの公式ドキュメントでもMavenによるUsageが記載されているが、
Gradleの簡潔さは、Mavenにおける pom.xml の冗長さに苦戦していた身としてはすこぶるラクに思えた。