Posted at

Javaで実装したWebシステムを試しにKotlinへ移行してみた

More than 3 years have passed since last update.

この記事は リクルートライフスタイル Advent Calendar 2015リクルートライフスタイル Advent Calendar 2015 - Qiita の15日目です。

ホットペッパービューティーで開発を担当しているyubakenです。

Kotlin Blog では最近1.0.0ベータ版のリリース記事が頻繁にあがっていますね。

私も1.0.0に向けてKotlinで何か書こうと考えておりましたが、何が出来るかについては公式ドキュメントでしたり他の方が記事のほうがよくまとまっていました。

なので、私はホットペッパービューティーを動かしているJavaのソースコードの一画面分のControllerとServiceをKotlinに変換して動かせるか試してみた手順について書いていこうと思います。

※Kotlinって何出来るの?と気になった人は以下ページを参照

https://kotlinlang.org/docs/reference/idioms.html


環境


  • Kotlin:1.0.0-beta-3594

  • Java:6

  • フレームワーク:SAStruts+社内フレームワーク

  • IDE:IntelliJ IDEA Ultimate 5.0.2(以降、IntelliJ)


MavenにKotlinの依存性を追加

<dependencies>

...
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.0.0-beta-359</version>
</dependency>
</dependencies>


JavaのソースコードをKotlinへコピペして自動変換する

移行にはIntelliJを使用します。

まず移行したいファイルと同じ名前のktファイルを作成し、移行元の全ソースをコピーしてKtファイルに貼り付けます。

そうしますと「Clipboard content copied from Java file, Do you want to convert it to Kotlin code?」 と聞かれますので「Yes」を選択します。

これでktファイルへコピーしたJavaのソースコードがKotlin用に自動変換されます。

ですが、もちろんこれだけではコンパイルエラーが発生してしまいます。


DI(依存性の注入)をするプロパティ(メンバ変数)に対してLate Initializedする

Kotlinはプロパティの初期化が必要ですが、AutoWiredやResourceアノテーションのプロパティなど初期化できないものが出てくると思います。

そういったプロパティ向けにKotlinではLate Initializedという機能があります。

// Javaの場合

@Resource
JdbcTemplate jdbcTemplate;

// Kotlinの場合
lateinit var jdbcTemplate: JdbcTemplate;

これでプロパティの初期化が不要になりました。


プロパティのgetter/setter自動生成に対応する

移行元のソースコードでプロパティに対してのgetterメソッドが定義されている箇所にエラーがありました。

// 例

var x : List<String> = 1 // Kotlin: Platform declaration clash: The following declarations have the same JVM signature
fun getX: List<String> {
....
}

これはKotlinがコンパイル時にプロパティに対応するsetter/getterを自動で生成するためエラーになります。

エラーを回避するためにはプロパティ名、またはfunction名を変更しましょう。


classをopenに

これは原因がまだ分かっていないのですが、classをopenにしないと画面表示時にエラーになりました。

(SAStrutsのクラスローダーで読み込めなかった?)

// これはエラー

class SampleController{
...
}

// OK
open class SampleController{
...
}


細かいエラーはQuickFixで片付ける

これ以外にもエラーが発生していましたが、IntelliJのAlt+EnterのQuickFixで大体解決出来ました。

※今回は動かすことが目標なのでQuickFix任せにしてますが、商用で動かすものは修正方法が正しいかはしっかりと調査しましょう。


動かす

今回はControllerとServiceクラスのみ修正して動かしてみましたが、Javaと変わりないパフォーマンスで動作しました。

細かい箇所のテストは実施出来ていないので確認作業で所々バグが見つかるかも知れませんが、SAStrutsの古いフレームワークでも動作することを確認できました。


おまけ

Kotlinのブログ内に「What Kotlin feels like, it's less code」という記述がありましたので、本当にソースコードが少なくなったか移行した際のソースコードのByteを比較してみました。

http://blog.jetbrains.com/kotlin/2015/11/the-kotlin-language-1-0-beta-is-here/

Java Source
Kotlin Source
Javaとの差

Controller
37,208 bytes
34,020 bytes
-3.1KB

Service
109,636 bytes
103,890 bytes
-5.7KB

せいぜい3桁くらい減ってると予測してましたが、実際には5,000byteも減少していました。

あと、SpringBootもKotlin化してみたのでGithubに置いときます。

構成は[SpringBoot]+[JPA]+[Thymeleaf(使ってない)]でDBの値をjsonで表示出来るとこまで実装してます。

https://github.com/yubaken/springboot-kotlin-sample