mike、mikeなるままに…

プログラムに関してぬるま湯のような記事を書きます

gradle1.7のリリースノート超意訳

こんにちわ、みけです。

現在、gradle1.7-rc1が利用できます。

リリースノートの超意訳をどうぞ。


Gradle Release Notes

Version 1.7-rc-1

Gradle1.7になるとすごく速くなります。dependency解決とビルドスクリプトのコンパイルの改善をしました。Gradleユーザーみんなこの恩恵に預かれますが、でっかいプロジェクトだと、その効果はもっと顕著になります。パフォーマンスの改善とスケービリティがGradle1.7の主要なテーマになっています。

これらの改善点に加えて、Gradle1.7では面白い機能がついてきます。finalizer taskメカニズムによってタスクの結果がどうであれ、タスクの次に別のタスクを起動させることができるようになります。例えば、アプリケーションサーバーを起動するようなintegrationテスト(の失敗)の後にアプリケーションサーバーを終了させることができるようになります。コピーやアーカイブ生成時にファイルの重複をコントロールする機能が登場します。

Gradle1.7のBuild Setupプラグインの改善によりプロジェクトをテンプレートから生成する機能が利用可能になります。これにより新規プロジェクトの作成が簡単になります。

C++からネイティブバイナリーを作成する機能も進化します。ネイティブバイナリーの生成に関しては結構面倒な領域ですが、今後もGradleのこの分野での進化を期待して下さい。

Gradle1.7ではコア・テベロップチーム以外からのコントリビュートが多いのも特徴です。Gradle1.7に貢献してくださったデベロッパーの皆様に感謝しております。

Table Of Contents

新機能や追加機能

修正された問題

非推奨となったもの

潜在的な互換性に関わる変更

コントリビューター

既知の問題


新機能や追加機能

より速いGradleビルド

Gradle1.7でのビルドはより速くなります。

  • dependency解決が速くなります(ほとんどのビルドで改善効果が現れます)
  • テスト実行が高速化されます(特にログを大量に出力しているようなGradleで顕著です)
  • ビルドスクリプトのコンパイルが速くなります(Gradle1.6に比べて75%の時間でできるようになります)
  • 並行実行モードが高速になります

Finalizer tasks incubating

Gradle1.7から新しいタスク実行ルールが導入され、タスク終了時に他のタスクを起動することができるようになります。この機能はMarcin Erdmann氏によるものです。

Finalizer tasksではタスク終了時にそのタスクの結果にかかわらず別のタスクを起動します。

1
2
3
4
configure([integTest1, integTest2]) {
    dependsOn startAppServer
    finalizedBy stopAppServer
}

この例ではintegTest1タスクとintegTest2タスクの終了時にstopAppServerタスクを実行するように宣言されています。どちらか片方のタスクがビルドの最中に起動された場合もfinalizer taskが自動で実行されます。ビルドの最中に両方のタスクが起動された場合でも必ず両方のタスクの最後にfinalizer taskが実行されます。finalizer taskのstopAppServerはGradle実行時に起動タスクとして指定する必要はありません。

C++プロジェクトサポートの改善 incubating

GradleはC++プロジェクトのサポートをしていました。これはGradleをネイティブコードプロジェクトのビルドツールとして最良のものにする改善になります。

  • スタティックライブラリーの作成、リンク作成
  • 異なるC++ツールチェインでも利用可能になります(Visual C++、GCCなど)
  • 異なるアーキテクチャー、ビルドタイプ、OSへの対応
  • Variantに基づいた依存性解決
  • その他もろもろ(詳しくはこちらを見て下さい(英語))

JCenter レポジトリーのサポート incubating

Bintray’s JCenter Repositoryからdependencyを取得できるようになります。jcenter()レポジトリーノーテーションにより利用可能です。JCenterはコミュニティリポジトリーで、Bintrayから無料で配布可能です。

1
2
3
repositories {
    jcenter()
}

このスクリプトによりhttp://jcenter.bintray.comがApache Maven repositoryと同様にリポジトリーリストに追加されます。

パターン・ベース・ファイル・コピー設定 incubating

Gradle1.7ではきめ細かい設定によりどのファイルがコピーされるべきかを定義することができます。設定方法は”Ant Patterns”のように指定出来ます。この機能はKyle Marhan氏によるものです。

GradleにはファイルコピーのAPI(CopySpec)があり、アーカイブすることもできます。この新しい機能はより強力なものとなります。

1
2
3
4
5
6
7
8
task copyFiles(type : Copy) {
    from 'src/files'
    into "$buildDir/copied-files"
    // Replace the version number variable in only the text files
    filesMaching('**/*.txt') {
        expand version: '1.0'
    }
}

fileMatchingメソッドではClosureを引数に取り、FileCopyDetailsオブジェクトの設定を行うことができます。これと反対の動作をするfilesNotMatchingというメソッドもあり、パターンに該当しないファイルすべてを指定することもできます。

ファイル重複時のハンドリング機能 incubating

ファイルのコピーやアーカイブするときに、よく重複することがあります。そのような重複が発生した場合の処理方法を設定できるようになります。

1
2
3
4
5
task zip(type : Zip) {
    from 'dir1'
    from 'dir2'
    duplicatesStrategy 'exclude'
}

処理方法には2つあります。includeexcludeです。

includeストラテジーの場合、既存のGradleの動作と変わりありません。後からコピーされたもので上書きされます。なお、実際に発生した場合には警告が出力されるようになります。アーカイブ(zip、jar)の場合は新しいものが作成されます。

excludeストラテジーの場合、重複したファイルは無視されます。最初にコピーされたファイルが最終的に使われ、その後のファイルは無視され続けます。アーカイブの場合も同様で、最初に作成されたら、同じファイル名のものは作成されません。

1
2
3
4
5
6
7
8
9
10
11
task zip (type : Zip) {
    duplicatesStrategy 'exclude' // default strategy
    from ('dir1') {
        filesMatching('**/*.xml') {
            duplicatesStrategy 'include'
        }
    }
    from ('dir2') {
        duplicatesStrategy 'include'
    }
}

Gradle Wrapperはビルドスクリプトを特にいじらなくても利用可能になります incubating

Gradle WrapperWrapperタスクを定義しなくても利用できるようになります。つまりWrapperのためにビルドスクリプトをいじることはありません。

Wrapperを利用するためには単純に次のコマンドを実行するだけです。

1
$ gradle wrapper

Wrapperファイルがこれにより生成・設定されて、現在使用しているGradleのバージョンを利用することができるようになります。

なお、wrapperタスクをカスタマイズしたい場合は、ビルドスクリプトを次のように変更します。

1
2
3
wrapper {
    gradleVersion '1.6'
}

もし既存のWrapperタイプのタスクがある場合は、そちらが使われます。それ以外の場合はデフォルトのwrapperタスクが使用されます。

Javaライブラリーテンプレートプロジェクトの生成

build-setupプラグインがプロジェクトタイプをサポートするようになりました。Gradle1.7ではjava-libraryタイプが利用可能です。このタイプで生成されるのは以下のとおりです。

  • javaプラグインが適用されたシンプルなビルドファイル
  • サンプルのプロダクションクラスとディレクトリー
  • サンプルのJUnitテストとディレクトリー
  • Gradle Wrapperファイル

Javaライブラリープロジェクトを作る場合は次のコマンドを実行するだけです(build.gradleファイルは必要ありません)。

1
$ gradle setupBuild --type java-library

詳しくはこちらをBuild Setup pluginを参照して下さい。

publicationのカスタマイズ – new publishingプラグインにおける incubating

publishプラグインでアーカイブを発行するときにartifactの情報を明示的にカスタマイズできるようになりました。以前はartifactの情報はプロジェクトの情報から取得されていました。

MavenPublicationではgroupIdartifactIdversion情報を設定できるようになります。Mavenのpompackagingの値も設定可能です。

1
2
3
4
5
6
7
8
9
publications {
    mavenPub(MaenPublication) {
        from components.java
        groupId 'my.group.id'
        artifactId 'my-publication'
        version '3.1'
        pom.packaging 'pom'
    }
}

IvyPublicationではorganisationmodulerevisionを設定出来ます。IvyModuleDescriptorstatusの値も設定可能です。

1
2
3
4
5
6
7
8
9
publications {
    ivyPub(IvyPublication) {
        from components.java
        organisation 'my.org'
        module 'my-module'
        revision '3'
        descriptor.status 'milestone'
    }
}

この機能のすごいところは、moduleartifactIdを設定することができることです。というのも、これまではproject.nameを使っており、Gradleのビルドスクリプトで変更することができなかったためです。

複数のモジュールを一つのGradleプロジェクトから発行する incubating

publishプラグインでは複数のモジュールを一つのGradleプロジェクトから発行することが可能になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
project.group 'org.cool.library'
publications {
    implJar(MavenPublication) {
        artifactId 'cool-library'
        version '3.1'
        artifact jar
    }
    apiJar(MavenPublication) {
        artifactId 'cool-library-api'
        version '3'
        artifact apiJar
    }
}

これまでも可能でしたが、ここに示したような簡単な方法ではできませんでした。新しいivy-publishmaven-publishプラグインでは簡単に出来ます。

TestNGパラメーターがテストレポートに出力されます incubating

TestNGではparameterizing test methodsによってあるテストを複数回、異なるデータの入力でテストを行うことがサポートされています。以前のGradleのレポートでは、パラメタライズドテストは複数行にわたってレポートが出力されていましたが、そのテストの区別をすることができませんでした。テストレポートにはパラメーターのtoString()メソッドによる値を出力できるようにし、どのデータによるテストかを区別できるようにしました。

ParameterizedTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.testng.annotations.*;

public class ParameterizedTest {
    @Test(dataProvider = "1")
    public void aParameterizedTestCase(String var1, String var2) {
        // do testing
    }

    @DataProvider(name = "1")
    public Object[][] provider1() {
        return new Object[][] {
           {"1", "2"},
           {"3", "4"}
        };
    }
}

上記のテストに対するレポートは次のように表示されます。

  • aParameterizedTestCase(1, 2)
  • aParameterizedTestCase(3, 4)

この情報はGradleのHTMLテストレポートとJUnit XMLファイルに反映されます。JUnit XMLファイルは一般的にテストの実行結果をCIサーバーに引き渡す役割を担っており、CIサーバーでパラメーターの情報を参照することが可能になります。

テストタスクに標準的なレポートインターフェースを採用

レポートインターフェースによりレポートをコントロールする方法が提供されます。テストタスクではこのレポートインターフェースが採用されます。

1
2
3
4
5
6
7
apply plugin: 'java'
test {
    reports {
        html.enabled = false
        junitXml.destination = file("$buildDir/junit-xml")
    }
}

testタスクの提供するTestReports型のReportContainerを通じて、HTMLによるテストレポートおよびJUnit XMLファイルの出力の制御を行えるようになります(これらのファイルは通常CIサーバーやその他のツールとテスト結果を共有するために使われます)。

これによりテストタスクも他のレポート生成タスクとAPIレベルで同等になります。また、不要であればJUnit XMLファイルを生成しないことも可能です。

ビルドダッシュボードの改善 incubating

上記の変更(テストタスクに標準的なレポートインターフェースを採用)は言い換えると、テストレポートがビルドダッシュボードに現れるということです。

なお、buildDashbordタスクは自動的にレポート系タスクと同時実行されます(Finalizerタスクの機能により実現されています)。

JUnit XMLファイルでテストケースごとにテストの出力を表示するようになりました incubating

この変更によりJenkinsなどのCIサーバーでよりよいテスト結果を得ることができます。

JUnit XMLファイルはテスト結果のフォーマットとしてデファクト・スタンダードです。たいていのCIサーバーはこのファイルをテストの実行結果として使っています。元々は「JUnit And Tasks」によって考えられたもので、JUnitとほぼ同時期に作られ、多くの局面で使われてきましたが、特に仕様が定められていませんでした。

このファイルにはテスト中の標準出力(System.outSystem.err)の内容が収められています。これまでは出力はクラスレベルでのみ記録されていました。つまり、テストケース毎の出力が得られなかったわけです。しかしGradleでは「テストケース毎の出力」モードを利用することができるようになりました。

1
2
3
4
5
test {
    reports {
        junitXml.outputPerTestCase = true
    }
}

このモードを使うと、XMLレポートはテストケースごとに作成されます。Jenkins CIサーバーではテストケース毎の結果を参照できるようになります。outputPerTestCase = trueと設定しておくと、テストケース毎の出力が画面に表示されます。以前はテストクラス毎の出力でした。

JenkinsのJUnit Attachments Pluginはこの機能とともに用いることで有効活用できます。

ApplicationプラグインでJVMパラメーターを指定できるようになります incubating

Olaf KilschatによりApplication PluginはデフォルトのJVM引数を設定することができるようになります。

1
2
apply plugin: 'application'
applicationDefaultJvmArgs = ['-Dfile.encoding=UTF-8']

BndライブラリーのアップデートによりOSGiサポートが改善されました

OSGiプラグインはBndツールを使ってbundle manifestsを作成しています。Bndツールのバージョンが1.50.0から2.1.0に変更されます。

最も重要な変更点は”invokedynamic”命令を使うJavaコード用のmanifestが正確になることです。

修正された問題

Gradle1.7で30の問題が修正されました。

  • [GRADLE-642] – scala toolsまたはライブラリーが登録されていない場合にscalaタスクから出力されるエラーメッセージを修正
  • [GRADLE-1289] – “create-project”コマンドによるスケルトンプロジェクト作成機能を提供
  • [GRADLE-1372] – wrapperタスクをビルトインタスクにしました
  • [GRADLE-1387] – Gradle Architypes機能を提供
  • [GRADLE-1456] – Application PluginにてJAVA_OPTS/APPL_OPTSを設定する方法を提供
  • [GRADLE-1551]http://www.gradle.org/build_lifecycle.html%E3%81%AEtypo%E3%82%92%E4%BF%AE%E6%AD%A3
  • [GRADLE-1583] – Gradleがivy configurationの表現をサポートしていない
  • [GRADLE-1704] – “gradle —version”コマンドの日付フォーマットの修正
  • [GRADLE-1742] – CodeNarcの警告数の上限を設定できるようにした
  • [GRADLE-2171] – zipファイル生成する場合に重複を回避するオプションを提供
  • [GRADLE-2519]testReport = falseと指定していてもテストFAILURE時に存在しないファイルのURLが表示される
  • [GRADLE-2666] – maven2GradleでNullpointerが発生
  • [GRADLE-2702] – testRuntime/testCompile configurationがテストがなくても解決される
  • [GRADLE-2738] – dependenciesで同じartifactの複数のバージョンを指定している場合、一番古いバージョンで解決される
  • [GRADLE-2752] – 自分自身のライブラリーの古いバージョンに依存している場合に
  • [GRADLE-2760]--parallel-threadsが内部的に4つまでしか使えない
  • [GRADLE-2765] – XMLテストレポートを出力できない設定を追加
  • [GRADLE-2766] – Ivy defaultConfMappingが解決に用いられない
  • [GRADLE-2780] – Gradle1.6でスクリプトのコンパイルが劣化
  • [GRADLE-2790] – Ivy dependency configuration mapping '*->@' がターゲットモジュールからすべてのconfigurationを含んでしまう
  • [GRADLE-2791] – Ivy dependency configuration mapping で左項'%'が無視される
  • [GRADLE-2792] – Ivy dependency configuration mapping で左項'*,!A'がAの解決時に含まれてしまう
  • [GRADLE-2793] – Ivy dependency configuration mapping で右項'#'が不適切なターゲットconfigurationに解される
  • [GRADLE-2802] – Wrapperのインストール/ダウンロードが-g--gradle-user-homeコマンドラインフラグを考慮しない
  • [GRADLE-2806] – OSGiプラグインにBNDライブラリーの最新版を適用
  • [GRADLE-2808]setting options.forkOptions.executableと設定をしてjoint compileするとNotSerializableExceptionが発生する
  • [GRADLE-2813]project.exec()でタスクを定義した場合、DSLが反映されない
  • [GRADLE-2815]@Inputboolean型のgetterでis*という名前のメソッドには適用されない
  • [GRADLE-2821] – テストのないテストタスクのレポート出力時にTestReportタスクがエラーを出力
  • [GRADLE-2825]strategyincludeに設定されていてもファイル重複の警告が出力される

非推奨となったもの

Gradleの進化にともなって置き換えられたものや無駄になったものは非推奨になり、次のメジャーバージョン(Gradle2.0)にて廃止されます。ユーザーガイドのFeature Lifecycleを参照して下さい。

以下に示すのが今回非推奨となったものです。もし何かあればGradle Forumsで問題提起してください。

テストレポートプロパティ

TestタスクがReportingインターフェースを実装するようになりました。現状のレポート出力に関するAPIは非推奨になりました。

  • disableTestReport()
  • enableTestReport()
  • isTestReport()
  • setTestReport()
  • getTestReportDir()
  • setTestReportDir()
  • getTestResultsDir()
  • setTestResultsDir()

すべての非推奨となった機能は新しいReporting機能でも利用可能ではあります。

潜在的な互換性に関わる変更

インメモリーdependencyキャッシング

パフォーマンスの改善により、Gradleはdependencyの記述をビルド全般にわたってメモリーにキャッシュするようになりました。つまりビルドの最中にdependencyメタデータが変わると、その変更はGradleは検知されない場合があります。このようなことが発生するパターンは確かめられていませんが、理論上想定することができます。

詳しくはFaster Gradle Buildsを参照下さい。

incubatingのJaCoCoプラグインの変更

JaCoCoカバレージプラグインのいくつかのクラスのプロパティの名前が適切なものに置き換わりました。

  • JaCoCoTaskExtension.destPathdestinationFileになりました。
  • JaCoCoTaskExtension.classDumpPathclassDumpFileになりました。
  • JaCoCoMerge.destFiledestinationFileになりました。

incubatingのbuild-setupプラグインの変更

ConvertMaven2GradleGenerateBuildScriptGenerateSettingsScriptクラスが削除されました。それらはSetupBuild型のbuildSetupタスクの一部となっています。

プラグインはbuild-setupタイプに基づいて異なるタイプ・名前のタスクを作成します。

setupWrapperタスクはwrapperとなっています。

incubatingのivy-publishプラグインにおけるタスク名の変更

maven-publishプラグインとの統一性を計るため、IvyPublicationでivy.xmlを生成するタスクが変わりました。タスクの名前はgenerateDescriptorFileFor${publication.name}Publicationとなります。

IvyPublicationのデフォルトstatus値がintegrationとなり、project.statusでなくなりました incubating

Ivy publicationモデルからGradleプロジェクトモデルを分離するために、ivy-publishプラグインで発行する際にproject.statusの値は使われなくなりました。

IvyPublicationIvyModuleDescriptor用にstatusの値が設定されていない場合、デフォルトのivyステータス('integration')が使われます。以前はproject.statusのデフォルト値である'release'が使われていました。

C++サポートの大幅な変更

GradleのincubatingなC++サポートがメジャーアップデートします。多くのプラグイン、タスク、APIクラス、DSLが変わります。この変更に伴いほとんどのシンプルなC++ビルドを変更する必要があります。

既存のC++ビルドを今後もGradleで実行するための対策は2つあります。

  1. Gradleを1.6のままにして、C++のサポートが安定するのを待ちます。その後、更新します。
  2. 最新の変更にビルドを合わせるようにします。なお、新たにリリースされた場合には変更が発生する可能性があります。

ConfigureableReportConfigurableReportに名称が変わりました

incubatingのorg.gradle.api.reporting.ConfigureableReportクラスはorg.gradle.api.reporting.ConfigurableReportクラスに変更されます。ミススペルが原因です。

テストがない場合テストタスクがスキップされるようになりました

テストがない場合には、テストタスクはスキップされるようになります。GRADLE-2702

以前はテストがない場合であっても、テストが実行されていました。その結果、dependencyの解決が実行され、何もないテストレポートが出力されていました。この変更によりビルドが高速になります。また、既存のビルドに対して大きな影響は発生しません。

OSGiプラグインに使われているBndライブラリーがアップデートされました

OSGiプラグインでbundle manifestの生成に使われていたBndツールのバージョンが1.50.0から2.1.0に上がります。

この変更は重要なアップグレードですが、後方互換性があります。

コントリビューター

Gradleコミュニティの他に、Gradleのディベロップメントチームは下記の人達にこのバージョンのGradleへの貢献に感謝します。

Marchin Erdmann
  • Finalizer tasks
Dan Stine
  • CodeNrcプラグインのmaxPriorityViolations setting (GRADLE-1742)
  • ユーザーガイドの修正
Kyle Mahan
  • アーカイブ・コピー操作における重複への対処(GRADLE-2171)
  • パターン・ベース・ファイル・コピー設定
Robert Kühne
  • ユーザーガイドのスペルミス修正
Björn Kautler
  • Build Dashboard のサンプルの修正
Seth Goings
  • ユーザーガイドの修正
Scott Bennett-McLeish
  • ユーザーガイドの修正
Wujek Srujek
  • wrapperのインストールロケーションに関する-gコマンドラインオプションの処理(GRADLE-2802)
Guillaume Laforge
  • OSGiプラグインのBndライブラリーアップデート(GRADLE-2806)
Yoav Landman

既知の問題

今のところGradle1.7に問題は見つかっていません。