Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java開発者向けのKotlin Gradleビルドスクリプト入門 / Gradle Build Script in Kotlin 101

Kengo TODA
October 28, 2022

Java開発者向けのKotlin Gradleビルドスクリプト入門 / Gradle Build Script in Kotlin 101

Server-Side Kotlin Meetup vol.6 『Java開発者向けのKotlin』で発表したLTです。
https://server-side-kotlin-meetup.connpass.com/event/262538/

Kengo TODA

October 28, 2022
Tweet

More Decks by Kengo TODA

Other Decks in Programming

Transcript

  1. Copyrights(c) Henry, Inc. All rights reserved.
    1 Copyrights(c) Henry, Inc. All rights reserved.
    Java開発者向けのKotlin
    Gradleビルドスクリプト入門
    2022年10月28日

    View full-size slide

  2. Copyrights(c) Henry, Inc. All rights reserved.
    自己紹介
    Kengo TODA (@kengo_toda)
    株式会社ヘンリー SRE
    Java界では静的解析ツールSpotBugsの中の人、
    または@actions/setup-java に依存キャッシュ機能を入
    れた人として知られているといいなぁ
    2

    View full-size slide

  3. Copyrights(c) Henry, Inc. All rights reserved.
    本日の目標
    Java開発者が
    Kotlin DSLで書かれたGradleのビルドスクリプトを
    読めるようになる💪
    3

    View full-size slide

  4. Copyrights(c) Henry, Inc. All rights reserved.
    アジェンダ
    1. GradleスクリプトをKotlinで書く利点
    2. Kotlinで書いたGradleスクリプトとはどのようなものか
    3. Java開発者から見てわかりやすい部分
    4. Java開発者から見てわかりにくい部分
    5. おまけ
    4

    View full-size slide

  5. Copyrights(c) Henry, Inc. All rights reserved.
    5
    GradleスクリプトをKotlinで書く利点

    View full-size slide

  6. Copyrights(c) Henry, Inc. All rights reserved.
    Javaと同じ静的型付け言語
    Kotlin
    コードを実行する前から多くの問
    題を認識できる
    IDEの補完が効いたり、定義に
    ジャンプして確認ができたりと
    いった使いやすさがある
    Groovy
    動的型付け。近年のトレンドから
    離れる感じ(著者所感)
    IDEの補完が効きにくく、ビルドス
    クリプトが書きにくい
    6

    View full-size slide

  7. Copyrights(c) Henry, Inc. All rights reserved.
    Groovyをキャッチアップをしなくて済む
    Kotlin
    Android公式言語。
    ベターJavaとしての地位も確立し
    つつあるので、試しておいて損は
    ない(気がする)
    Groovy
    最近はGradleとJenkinsfileくらい
    でしか見ない(気がする)
    製品・サービスの開発で使わない
    言語をビルド設定のためだけに
    学ぶ・学ばせるのは面倒
    7

    View full-size slide

  8. Copyrights(c) Henry, Inc. All rights reserved.
    KotlinならJavaエンジニアでも簡単に
    ビルドスクリプトが書ける?

    View full-size slide

  9. Copyrights(c) Henry, Inc. All rights reserved.
    GradleビルドスクリプトにありがちなKotlin謎
    機能
    plugins { // if みたいなブロック?
    java // 何で囲うのが正解かよくわからない
    id("jacoco")
    `maven-publish`
    }
    // 唐突に出てくる<>
    tasks {
    named("test") {
    testLogging.showExceptions = true
    }
    }
    // 変数の初期化に=ではなくbyを使っている
    val fooVersion: String by settings
    // byはcreating, registeringなどと組み合わせることも
    val barTask by tasks.creating(Bar::class) {
    // …
    }
    // 値の代入に=ではなくset()を使うこともある
    tasks.named("bootJar") {
    mainClassName = "com.example.demo.Demo"
    archiveFileName.set("app.jar")
    }
    9

    View full-size slide

  10. Copyrights(c) Henry, Inc. All rights reserved.
    直感的なところから少しずつ慣れていこう

    View full-size slide

  11. Copyrights(c) Henry, Inc. All rights reserved.
    11
    Java開発者から見てわかりやすい部分

    View full-size slide

  12. Copyrights(c) Henry, Inc. All rights reserved.
    変数、文字列、コメント
    // Javaのvarのように使う
    val myVariable = "foo"
    // 型を明示しても良い
    val anotherVariable : String = "bar"
    // 文字列テンプレート
    println("バージョン $version をビルドしています")
    12

    View full-size slide

  13. Copyrights(c) Henry, Inc. All rights reserved.
    関数、ラムダ式
    // 関数定義はJavaというよりはJavaScriptっぽい
    fun greeting(name: String): Unit {
    println("Hello, $name!")
    }
    // ラムダ式もある
    val goodBye = { name: String -> println("Good bye, $name") }
    13

    View full-size slide

  14. Copyrights(c) Henry, Inc. All rights reserved.
    ここでちょっと応用
    14

    View full-size slide

  15. Copyrights(c) Henry, Inc. All rights reserved.
    Passing trailing lambdas
    // 最後の引数が関数型の場合、ラムダをカッコの外に書いても良い
    val product = items.fold(1) { acc, e -> acc * e }
    // 引数が関数型のものひとつしか無いなら、カッコも省略できる
    run { println("...") }
    15

    View full-size slide

  16. Copyrights(c) Henry, Inc. All rights reserved.
    ブロックのようなものは引数としてのラムダ式
    // これはifのようなブロックではなく、ラムダ式を引数にとる関数の実行
    plugins {
    id("jacoco")
    }
    // これ↑はこれ↓と同じ
    plugins({
    id("jacoco")
    })
    16

    View full-size slide

  17. Copyrights(c) Henry, Inc. All rights reserved.
    ジェネリクス(1)
    Javaとだいたい同じだけどより優しい
    interface Source {
    fun nextT(): T
    }
    fun demo(strs: Source) {
    val objects: Source = strs
    // This is OK, since T is an out-parameter
    }
    17

    View full-size slide

  18. Copyrights(c) Henry, Inc. All rights reserved.
    ジェネリクス(2)
    tasks {
    named("test") {
    // thisがTest型になっている
    testLogging.showExceptions = true
    }
    }
    18

    View full-size slide

  19. Copyrights(c) Henry, Inc. All rights reserved.
    19
    Java開発者から見てわかりにくい部分

    View full-size slide

  20. Copyrights(c) Henry, Inc. All rights reserved.
    識別子(1)
    // バッククォートで囲むと識別子にダッシュを使える
    plugins {
    `java-library` // これは文字列ではなく識別子
    }
    // Javaでは不要だった配慮が必要なことも
    standardInput = System.`in`
    20

    View full-size slide

  21. Copyrights(c) Henry, Inc. All rights reserved.
    識別子(2)
    // 数値から始めることもでき、テストメソッドの名付けに便利
    fun `0歳の患者に対して実行すると月齢まで表示される`() {
    // …
    }
    21

    View full-size slide

  22. Copyrights(c) Henry, Inc. All rights reserved.
    byによる委譲(1)
    // gradle.properties から値を取り出す
    val fooVersion: String by settings
    // byによってプロパティの取得をSettingsインスタンスに委譲している。このインス
    タンスにはgradle.propertiesに書かれた設定がreadonlyのプロパティとして設定
    されている。
    //
    // つまり以下と同じ動作となる。変数名が重複している点に注目。
    val fooVersion: String = settings.fooVersion
    22

    View full-size slide

  23. Copyrights(c) Henry, Inc. All rights reserved.
    byによる委譲(2)
    // タスクを作る
    val barTask by tasks.creating(Bar::class) {}
    // tasks.creating() はPolymorphicDomainObjectContainerCreatingDelegateProvider
    // インスタンスを返す。このクラスには以下のメソッドが実装されている:
    operator fun provideDelegate(thisRef: Any?, property: KProperty<*>) =
    ExistingDomainObjectDelegate.of(
    when (configuration) {
    null -> container.create(property.name, type)
    else -> container.create(property.name, type, configuration)
    }
    )
    23

    View full-size slide

  24. Copyrights(c) Henry, Inc. All rights reserved.
    byによる委譲(3)
    // つまりこの書き方は、
    val barTask by tasks.creating(Bar::class) {}
    // この書き方と同じ。変数名が重複している点に注目。
    val barTask = tasks.create("barTask", Bar::class) {}
    24

    View full-size slide

  25. Copyrights(c) Henry, Inc. All rights reserved.
    25
    まとめ

    View full-size slide

  26. Copyrights(c) Henry, Inc. All rights reserved.
    GradleビルドスクリプトにありがちなKotlin謎
    機能 回答編
    plugins { // ラムダ式を引数に取る関数
    java
    id("jacoco")
    `maven-publish` // ダッシュを含む識別子
    }
    // 戻り値がTest型であることを明示
    tasks {
    named("test") {
    testLogging.showExceptions = true
    }
    }
    // 委譲によって重複を排除
    val fooVersion: String by settings
    val barTask by tasks.creating(Bar::class) {
    // …
    }
    // Gradle側の課題なのでKotlinは悪くないです🥺
    // https://github.com/gradle/build-tool-roadmap/issues/38
    tasks.named("bootJar") {
    mainClassName = "com.example.demo.Demo"
    archiveFileName.set("app.jar")
    }
    26

    View full-size slide

  27. Copyrights(c) Henry, Inc. All rights reserved.
    27
    ご参加ありがとうございました!

    View full-size slide

  28. Copyrights(c) Henry, Inc. All rights reserved.
    28
    We are Hiring !

    ● 医療DX

    ● 難しい課題の解決

    ● 社会貢献


    これらのキーワードが気になる方、

    一度カジュアルにお話ししましょう!


    採用サイト

    https://jobs.henry-app.jp/

    28

    View full-size slide