Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

Copyrights(c) Henry, Inc. All rights reserved. 28 We are Hiring ! 
 ● 医療DX
 ● 難しい課題の解決
 ● 社会貢献
 
 これらのキーワードが気になる方、
 一度カジュアルにお話ししましょう!
 
 採用サイト
 https://jobs.henry-app.jp/
 28