DEV Community

kaede
kaede

Posted on • Updated on

kotlin 基礎 Part 11 -- Spring で マルチモジュールの Kotlin プロジェクトを作成する

IntelliJ が動くようにする。


IntelliJ の DL

https://www.jetbrains.com/idea/download/#section=mac

公式サイトに行く。

Image description

macOS の コミュニティ エディションの DMG ファイルを DL する。


IntelliJ の起動

Image description

IntelliJ が開けることを確認する。


便利プラグインを入れる

https://dev.to/kaede_io/intellij-chu-qi-she-ding-tocao-zuo-3003

この記事に書いた。

IdealVim など。



Spring アプリが動くようにする


Spring アプリの作成

https://start.spring.io/

このサイトで Springboot のアプリを作成する。

https://dev.to/kaede_io/kotlin-de-springboot-noapuriwozuo-cheng-siteqi-dong-suru-2a9l

前の記事を参考に作成

  • Project: Gradle:Kotlin
  • Language: Kotlin
  • Springboot: 3.0.2
  • Group: com.kaede
  • Name, Artifact: kotlin1
  • Java: 17
  • Dependencies: Spring Web

これらの設定で作成する。

https://start.spring.io/#!type=gradle-project-kotlin&language=kotlin&platformVersion=3.0.2&packaging=jar&jvmVersion=17&groupId=com.kaede&artifactId=kotlin1&name=kotlin1&description=1st%20Project%20by%20kotlin%20in%20Mac&packageName=com.kaede.kotlin1&dependencies=web

このリンクから上記の設定で開ける。

これを DL する。


IntelliJ で kotlin1 のプロジェクトを開く。

Image description

上記のプロジェクトを IntelliJ で開く。
しばらく待つと、実行可能になる。


main から実行して Spring アプリが起動するのを確認

Image description

実行すると Tomcat が 8080 で起動するのが見れる。
これで Spring アプリの起動は確認できた。


Hello World を確認

fun main(args: Array<String>) {
    runApplication<Kotlin1Application>(*args)
    println("Hello Kotlin1")

}
Enter fullscreen mode Exit fullscreen mode

main に Hello World の文字列を入れる。

2023-02-06T17:56:33.534+09:00  INFO 94815 --- 
[           main] 
com.kaede.kotlin1.Kotlin1ApplicationKt   : 
Started Kotlin1ApplicationKt in 3.191 seconds 
(process running for 3.77)
Hello Kotlin1
Enter fullscreen mode Exit fullscreen mode

これで起動すると、Hello Kotlin1 の文字列がログとしてみれた。



サブモジュール rest を作り、起点にする。


rest モジュールを Java で作成

まず rest モジュールを kotlin1 のアプリに作成

左上の File から New -> Module を選ぶ。

  • Name: rest
  • Language: Java
  • Bulid System: Gradle
  • Gradle DSL: Kotlin
  • parent: kotlin1

これらを指定してモジュールを作成。

すると

 

kotlin1/rest/src/main/java/com/kaede/Main.java
Enter fullscreen mode Exit fullscreen mode

ここまで生成される。
この時に main/ には kotlin の言語空間は作成できない。


rest モジュールで Kotlin が無効なことを確認

マルチモジュールにすると、そのままではサブモジュールで Kotlin を使用することができない。設定ファイルを書き換える必要がある。

まずはルートのプロジェクトから、main/ 下の kotlin/ をコピーする。

これを rest/src/main にコピーする。

java/ と違って kotlin/ は青色になっていない。
この段階では、言語フォルダとして認められていないからだ。
なので当然、main 関数は実行できない。


 ルートの build.gradle.kts を変更


springframework.boot の無効化

https://qiita.com/purini-to/items/6070c29ac4ed086e06be#main%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8C%E7%84%A1%E3%81%84%E3%82%88%E3%81%A3%E3%81%A6%E6%80%92%E3%82%89%E3%82%8C%E3%82%8B

この記事を見るまでわからなくて何日も費やした。

plugins {
    //id("org.springframework.boot") version "3.0.2"
    id("io.spring.dependency-management") version "1.1.0"
    kotlin("jvm") version "1.7.22"
    kotlin("plugin.spring") version "1.7.22"
}
Enter fullscreen mode Exit fullscreen mode

springframework.boot は無効化する。
サブプロジェクト ( rest ) で有効化する。
起点は rest だからだと解釈した。


subprojects に plugin, dependences, tasks を移行する

subprojects というスコープを作る。
これで内部の設定を子供モジュールにも反映させられる。

これによって、kotlin が子供モジュールでも使えるようになると解釈。

subprojects {
    apply(plugin = "org.jetbrains.kotlin.jvm")
    apply(plugin = "io.spring.dependency-management")

    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")
        testImplementation("org.springframework.boot:spring-boot-starter-test")
    }
    tasks.withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "17"
        }
    }
    tasks.withType<Test> {
        useJUnitPlatform()
    }
}
Enter fullscreen mode Exit fullscreen mode

詳細としては

設定ファイルの前半にグローバルで書かれている

  • kotlin.jvm
  • spring.dependency-management

これらを 子供モジュール の内部で有効化している。

これで 子供モジュールでも kotlin や spring が使える。

また、dependencies としてグローバルに書いていた

  • spring-boot-starter-web
  • jackson-module-kotlin
  • kotlin-reflect
  • kotlin-stdlib-jdk8
  • spring-boot-starter-test

これらも子供モジュールの中で使えるようになった。

tasks も jvm の実行のために必要、


rest モジュールで kotlin が有効化されていることを確認

Image description

  • 🟦 フォルダ名が青くなっている
  • 🟩 main に実行可能を表す、緑三角が現れている

これにより、サブモジュールである rest モジュールで、Kotlin が有効化されていることを見れた。


rest の main を叩いてみる

https://stackoverflow.com/questions/54543168/spring-tool-suite-configuration-class-may-not-be-final-remove-the-final-modif

open class MultiprojectApplication
Enter fullscreen mode Exit fullscreen mode

サブモジュールでは main は open クラスじゃないとアプリケーションを起動できなかったので注意。

これを修正した上で、実際に rest の main を叩いてみる

2023-02-07  INFO 99845 --- [main] 
com.kaede.kotlin1.RestApplicationKt : 
Started RestApplicationKt in 3.316 seconds 
(process running for 4.206)
Hello REST
Enter fullscreen mode Exit fullscreen mode

rest を起点としてで Spring アプリが起動することを確認できた。


不必要なコードを消す

ルートの
src/main/kotlin/ 以下は消す。使わないので。
src/test/kotlin/ も同時に消す。
テストだけ残すとビルドが落ちるので。

また、rest/src/main/java/ 以下も消す。
ビルド時にこっちが読み込まれる時があるので。


ビルドして実行してみる

これができるまでかなり時間がかかった。

./gradlew build                                  

BUILD SUCCESSFUL in 2s
9 actionable tasks: 9 up-to-date
Enter fullscreen mode Exit fullscreen mode

コマンドでビルドして

java -jar rest/build/libs/rest-0.0.1-SNAPSHOT.jar
Enter fullscreen mode Exit fullscreen mode

スナップショット.jar を実行すると

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.2)


main] com.kaede.MultiprojectApplicationKt      : 
Starting MultiprojectApplicationKt 
using Java 17.0.2 with PID 87742 (/Users/kaede0902/code/multiproject/rest/build/libs/
rest-0.0.1-SNAPSHOT.jar started by kaede0902 
in /Users/kaede0902/code/multiproject)

main] com.kaede.MultiprojectApplicationKt      : 
Started MultiprojectApplicationKt in 3.937 seconds 
(process running for 4.735)
Enter fullscreen mode Exit fullscreen mode

無事にビルドされた jar ファイルから実行することができた。

これで Docker build して ECS コンテナで動かすことができるようになった。



おまけ


まだ API としては機能しないことを確認

curl localhost:8080
{"timestamp":"2023-02-06T08:47:23.695+00:00","status":404,"error":"Not Found","path":"/"}
Enter fullscreen mode Exit fullscreen mode

この段階で localhost 8080 を叩いても 404 しか返ってこない。

理由は GET MAPPING が設定されていないから。

なので、次は RestController を入れて、API として機能するようにする。


RestController と GetMapping で API レスポンスを受け取るようにする

src/main/kotlin/com/kaede/

ここに先ほど作った RestApplication.kt がある。
これと並列に PersonResouce.kt を作成

@RestController
class PersonHandler {
    @GetMapping("/")
    fun root(): String {
        println("root accessed")
        return "Hello From PersonResource"
    }
}
Enter fullscreen mode Exit fullscreen mode

ルートへのアクセスを受け取って、
Hello From PersonResource のレスポンスを返すようにする


ルートへの curl で動作確認

kaede0902@rooter kotlin1 % curl localhost:8080/
Hello From PersonResource%  
Enter fullscreen mode Exit fullscreen mode

ちゃんと帰ってきた。

これで Rest モジュールで API のエンドポイントが作れた。

Top comments (0)