Spring Boot + gRPCの設定について躓いたところ【Kotlinサーバーサイドプログラミング実践開発】

# はじめに

今回は以下の書籍の9章高速な通信フレームワークgRPCでつまづいたところをまとめていきます

https://www.amazon.co.jp/Kotlin-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%B5%E3%82%A4%E3%83%89%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%AE%9F%E8%B7%B5%E9%96%8B%E7%99%BA-%E7%AB%B9%E7%AB%AF-%E5%B0%9A%E4%BA%BA/dp/4297118599/ref=sr_1_5?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=4Z8WX9CS4366&keywords=kotlin&qid=1673140197&sprefix=kotli%2Caps%2C218&sr=8-5

行ったのは、3 Spring BootでgRPCのKotlinサーバーサイドプログラグを実装の箇所となります。その前にも実装箇所はありますが、実践ではフレームワークを利用することが多いので飛ばしました

# 設定ファイルを作る

`build.gradle.kts`がそもそも現在のJava17だと動きません
サンプルは11になっていました

https://qiita.com/Nash-BETA/items/0f356934255612cb096d

そこで、Spring Initializrの17で作成したプロジェクトに必要な依存を追加した以下のファイルを作成しました


```kotlin:build.gradle.kt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import com.google.protobuf.gradle.generateProtoTasks
import com.google.protobuf.gradle.id
import com.google.protobuf.gradle.plugins
import com.google.protobuf.gradle.protobuf
import com.google.protobuf.gradle.protoc

plugins {
    id("org.springframework.boot") version "3.0.1"
    id("io.spring.dependency-management") version "1.1.0"
    id("com.google.protobuf") version "0.8.15"
    id("idea")
    kotlin("jvm") version "1.7.22"
    kotlin("plugin.spring") version "1.7.22"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("io.grpc:grpc-kotlin-stub:1.0.0")
    implementation("io.grpc:grpc-netty:1.35.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.4.2")
    implementation("io.github.lognet:grpc-spring-boot-starter:4.4.4")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "17"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.15.1"
    }
    plugins {
        id("grpc") {
            artifact = "io.grpc:protoc-gen-grpc-java:1.36.0"
        }
        id("grpckt") {
            artifact = "io.grpc:protoc-gen-grpc-kotlin:1.0.0:jdk7@jar"
        }
    }
    generateProtoTasks {
        all().forEach {
            it.plugins {
                id("grpc")
                id("grpckt")
            }
        }
    }
}
```
この設定ファイルは[公式](https://github.com/google/protobuf-gradle-plugin/blob/master/examples/exampleKotlinDslProject/build.gradle.kts)が出しているものを参考にして作るようなので基本的には置き換えで良いみたいです

そしてこのファイルでアプリケーションを実行したところ以下エラーが発生します

```
エラー: シンボルを見つけられません
@javax.annotation.Generated(
                 ^
  シンボル:   クラス Generated
  場所: パッケージ javax.annotation
```

`GreeterGrpc.kt`でエラーが出ています

そして以下の記事を見つけました

https://qiita.com/noobar/items/760c9b8210dab1cb9af4

`'javax.annotation:javax.annotation-api:1.3.2'`を依存に追加すると治るようです

最終的には以下のファイルにすることで無事プログラムを起動することができました

```kotlin:build.gradle.kt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import com.google.protobuf.gradle.generateProtoTasks
import com.google.protobuf.gradle.id
import com.google.protobuf.gradle.plugins
import com.google.protobuf.gradle.protobuf
import com.google.protobuf.gradle.protoc

plugins {
    id("org.springframework.boot") version "3.0.1"
    id("io.spring.dependency-management") version "1.1.0"
    id("com.google.protobuf") version "0.8.15"
    id("idea")
    kotlin("jvm") version "1.7.22"
    kotlin("plugin.spring") version "1.7.22"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("io.grpc:grpc-kotlin-stub:1.0.0")
    implementation("io.grpc:grpc-netty:1.35.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.4.2")
    implementation("io.github.lognet:grpc-spring-boot-starter:4.4.4")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    implementation("javax.annotation:javax.annotation-api:1.3.2")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "17"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.15.1"
    }
    plugins {
        id("grpc") {
            artifact = "io.grpc:protoc-gen-grpc-java:1.36.0"
        }
        id("grpckt") {
            artifact = "io.grpc:protoc-gen-grpc-kotlin:1.0.0:jdk7@jar"
        }
    }
    generateProtoTasks {
        all().forEach {
            it.plugins {
                id("grpc")
                id("grpckt")
            }
        }
    }
}
```

# おわりに

バージョンに依存しているものが多く、書籍が新しいものがないため書籍をやり切るのにもかなりの体力を取られる難しい内容だなと思いました

しかし、山場はなんとか超えられた気がするので残り3章がんばります

# 参考

https://qiita.com/Nash-BETA/items/0f356934255612cb096d

https://qiita.com/noobar/items/760c9b8210dab1cb9af4

https://github.com/google/protobuf-gradle-plugin/blob/master/examples/exampleKotlinDslProject/build.gradle.kts