Java / Gradle ビルド時に、リソースファイルを生成する。

ビルド時にリソースファイルを生成

この記事では、
Javaのプロジェクトで
ビルド時に、リソースファイルを生成する方法について、
記載していきます。

方法としては、Gradleでリソース生成のタスクを作り、
ビルド時に、そのタスクが自動で動くように設定します。

リソースファイルとは 

リソースファイルとは、
src/main/resources ディレクトリ配下などに、配置しておくファイルです。

Javaのコードから、
リソースファイルにアクセスするには、
クラスローダーを使います。

URL url = getClass().getClassLoader().getResource("sample.txt");

try {
    URI uri = Objects.requireNonNull(url).toURI();
    File file = new File(uri);

    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }

} catch (Exception e) {
    e.printStackTrace();
}

getResourceAsStream を使う方法もあり。

リソースファイルにしておくと、
Jarファイルとして、ファイルを含めた状態で配布が可能です。
Javaからいつでもアクセスできる状態にできます。

リソース生成タスクをつくる

Gradleのタスクで、
リソースファイルを生成するような、タスクを作りましょう。

タスクの定義は、build.gradle ファイルに記載します。
書き方は下記のとおり

task <タスク名> {
    doLast {
        <処理>
    }
}

処理の内容は、Groovyコードで実装します。
単純にresourcesディレクトリ配下に、
ファイルを作成して、文字列を書き込むだけです。

task createResource {
    doLast {
        def file = new File("src/main/resources/sample.txt")
        file.write "hoge"
    }
}

このタスクで、自分の埋め込みたい情報を追加してみましょう。
※親ディレクトリは、先に存在する状態でないとだめです。

dependsOn とは

さて、リソースファイルを生成するタスクは、作り方はわかりましたが、
自動で実行するにはどうすればいいでしょう。

Gradleは、タスクに依存関係が設定されています。
タスクを実行した際は、その依存関係をもとに、
必要なタスクが、正しい順番で実行されるようになっています。

dependsOn を使うと、
この依存関係を新たに設定することができます。

タスク依存関係の書き方

<タスク名A>.dependsOn <タスク名B>

タスクAは、タスクBに依存すると定義できます。
タスクAを実行した際に、先にタスクBが自動的に実行されるようになります。

タスクの依存関係

例えば、./gradlew build とした時に、
どういうタスクが順番に実行されるのか、知っておきましょう。

タスクの実行順番

$ ./gradlew build
> Task :compileJava
> Task :processResources
> Task :classes
> Task :jar
> Task :assemble
> Task :compileTestJava
> Task :processTestResources
> Task :testClasses
> Task :test
> Task :check
> Task :build

Javaコードのコンパイルのあと、
processResourcesというタスクが動作しているのがわかります。

このタスクの前に、
今回作ったリソースファイル生成タスクを、
実行してもらえれば良さそうですね。

リソースファイルを埋め込む事ができそうです。

processResources.dependsOn createResource

実装サンプル

更に、実践的な実装サンプルとして、
ビルドした時刻と、gitのリビジョンを、
リソースファイルとして、埋め込むものを記載しておきます。

ビルド時刻とリビジョンを埋め込む

build.gradle

// タスク実装で使うクラスはインポート必要
import groovy.json.*
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

// ~ 省略 ~

// リソース生成タスク
task createResource {
    doLast {
        // ビルド時刻
        def now = LocalDateTime.now()
        // git リビジョン
        String rev = "git rev-parse HEAD".execute().text.trim()

        // Json文字列を生成
        def jsonBuilder = new JsonBuilder()
        jsonBuilder(
                built_at: now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                git_revision: rev)

        String json = jsonBuilder.toPrettyString()

        // リソースファイルとして保存
        new File("./src/main/resources/built.json").write(json)
    }
}

// ビルド時に自動で実行されるように、依存関係の設定。
processResources.dependsOn createResource

生成されるリソースファイル

{
    "built_at": "2020-03-23 23:23:00",
    "git_revision ": "bb01ae91c66587e8fe7b9b50cdc0b89dda23c483"
}

まとめ

Gradleタスクを使って、リソースファイルを生成できます。

リソースファイルは、成果物(Jarファイル)に含めることができ、
Javaのコードから、いつでもアクセス可能なリソースです。

Gradleのタスクには、
依存関係が設定されており、正しい順番で実行されます。
dependsOn でビルド時に、自動的に動作するように設定が可能です。

成果物のバージョンなど、
いろいろな情報を埋め込むのに利用できるでしょう。


Gradle taskのdoFirstとdoLast

コメントを残す