どうも、えいやです。
またお鉢が回ってきたので、担当させていただきます。
前回はJava8で楽になったか試そうとしたけど、中途半端で完成しませんでしたという記事を書きました。
これはひどい、というご意見ですが、ごもっともですね。
今回も似た感じで、Kotlinで楽しようとした感じの中途半端な記事です。
大体のことがそんな感じなので、大抵のことを誰か代わりにやってくれないかなぁと思っています。僕より役に立つ人が沢山いるといいな。
さて、今回は、WebアプリケーションにBetter JavaとしてKotlinを使う検討をやってみているという話です。
検討途中ですし、大して詳細に調べたわけでもないので、適当に聞き流してください。
弊社では、開発言語に特に縛りはないものの、Java、Scala、Groovyと言ったJVM言語で開発している事が多いです。
そういうわけで、しばらく前に1.0がリリースされ、やや安定期に入ってきた新しいJVM言語であるKotlinの評価を始めてみました。
ScalaもGroovyも15~12年前に開発されてから、最近はわりと安定、普及してきたのはそりゃいいんだけど、そろそろ新しめの言語にも触れておかないとね。
なお、Kotlinの開発元は、最近JVM向けの有償IDEで(たぶん)一番人気*1のIntelliJ IDEAを作っているJet Brains社です。
まず、Kotlinという言語の特徴ですが、JVM上で動くバイトコードにコンパイル可能、静的型付け、オブジェクト指向という点ではJavaと同じです。
さらに、Kotlinには型推論、宣言側変性(ジェネクリスの変性を宣言可能)、高階関数、ラムダ式(最近のJavaにはあるけど)、移譲の宣言、Null安全、スマートキャストなどの便利機能がついています。
Kotlinの文法や詳細は、公式ページに任せます。また、いろいろな人が日本語で解説してくださっています*2*3ので、そちらを見てください。
この記事では、弊社が開発しているWebアプリケーションで、どの程度使えるのかを検証してみた内容について述べます。
なお、2017年03月現在で、世間様でのKotlinの利用状況としてはAndroidの開発でやや人気が出てきたというところのようです。
今回は、Kotlinの採用可能性について、以下の点で調べています。
1)KotlinおよびKotlin製のWebApplicationFWでシステム構築・運用が可能か
2)アプリケーションのコード全体をKotlinに置き換えることが可能か
3)2)のコードの一部をKotlinに置き換えることが可能か
4)既存のアプリケーションから利用するライブラリを作成可能か
1)KotlinおよびKotlin製のWebApplicationFWでシステム構築・運用が可能か
検証の対象として、Kotlin製のWebApplicationFWで一番安心できそうなJetBrain社製の「Ktor」を検証してみました。
結果としては、個人的には簡単なWebApplicationを作るだけならイケるんじゃないか、という感想なのですが、コレをチームメンバーに使えというのは酷という感じです。
Ktorは、最小の作業で素早くKtolinでWebアプリケーションを作るフレームワークと自身の紹介に書いてある通り、初見の印象としてはNode.jsのExpressに似たコンパクトなルーティングと処理を記述する、非常にコンパクトな機能を提供しているイメージです。
ドキュメントがほぼ整備されていないので、Ktor本体のソースコードとサンプルのソースコードを頼りに一通り試してみました。
公式のサンプルからそう離れたことはやっていませんし、この記事が出来上がる頃にはまた変わっていると思うので、試したコードは載せません。
なお、ドキュメントのGetting Startedで紹介してあるコードは僕が検証している段階では動かなかったのですが、今確認したところ動くコードに変わっているようです。
現時点でのバーションは0.3ですので、現時点ではかなり多くの不備があるため、採用するとなるとOSS開発に協力しつつシステム構築を進める事になります。
それはそれで面白いとは思いますが、すぐに導入を決めるのは難しそうです。
他のWebApplicationも一応検証してみたのですが、まともに動かすのに時間がかかるもの、更新止まっているものばかりでちょっと。。。
数年前に期待されていたKaraやWasabi*4は開発が止まっている、か停滞しているみたいです。
なお、KtorはKaraやWasabiにインスパイアされているらしいので、それらの後継と言えるので、今一番安心できる開発体制なのではないでしょうか。
なお、WebApplicationというとサーバサイドって感じですが、KotlinはJavaScriptにトランスパイルする事ができるのでそういうFWもあるみたい*5です。検証してませんが。
2)アプリケーションのコード全体をKotlinに置き換えることが可能か
今のJava製のアプリケーションFWをそのまま使ってということですね。
まず、前提としてKotlinのコードはバイトコードにビルドされますし、Javaのライブラリもそのまま使うことが出来ます。なので、可能性ということであれば絶対に可能です。
あとはそれで開発が楽になったり、いいことがあるかということです。あと、既存コードからKotlinへの一挙置換となると現状のテストコードだけでは検証が難しそう、とかは一旦考えません。
弊社でJavaのプロジェクトと一部のScalaのプロジェクトでは、自社製のJavaWebApplicatrionFWを使用していますので、その仕様に則って、WebApplicationを作ったとしましょう。
検証のポイントは、FWの仕様が、Kotlinとミスマッチだったりしないか、ということです。
さらに、既存コードからの置き換えということで、KotlinのJava->Kotlin変換機能でどの程度楽にできるか、ということも検証してみます。
検証
次のプロジェクトを変換してみます。
このプロジェクトは、弊社製のWebApplicationFrameworkのAsta4Dで作成されており、簡単なHandlerとSnippetで構成されています。
本当はDB周りも試したかったのですが、この記事のためには時間切れです。
もし実行してみたかったら、次のコマンドで実行可能です。
git clone https://github.com/aya-eiya/java2kt1 cd java2kt1 git checkout JavaSmaple ./gradlew clean appRun
起動にはGrettyを使っています。
localhost:8080で以下の画面を見ることが出来ます。
上から、path/hello
に対して引数なしGet、引数(name)ありGet、Postを行います。
path/hello
からの返りはJsonで、Getに対しては{“message”:“hello ○○”}
を返し、Postに対しては{“name”:“○○”}
を返します。
Postで送ったNameはSessionに保存され、引数なしGetの返却値の一部およびPath/
の一番下の入力フォームの初期値として使用されます。
さて、Kotlinに変換をしていきます。
まず、InteliJのJava->Kotlin変換機能を使ってみます。メニューからは Code -> Convert Java File to Kotlin Fileで選べます。
変換後のソースはビルドが通りません。
どうやらNull許容のところで型違反と、valで初期化するように変換した値に代入をしているようです。
単純な方法でコンパイルが通るように修正したコードではアプリが起動しません。
どうやらNull安全の機能が問題で、Null許容型とNull不可型で型が違うため、Springの設定ファイルに書いてあるBeanの作成に失敗しているようです。
型を合わせてみるとこのエラーはなくなりました。
次はFactoryとして作っていたクラスで、staticなinstance()メソッドが実装されています。
このクラスのBeanの設定でfactory-methodにinstanceを指定していましたが、Kotlinではクラスにstaticなメンバを持つことが出来ないため、JavaからはCompanionオブジェクトを通じて呼ばなければなりません。
なのでFactory.CompanionをBeanに登録して、factory-beanにそのIDを指定します。
次は、UrlRuleがInitialize出来ない、というエラー。。。
その後、30分ほど色々試してみるものの、どこかしらでエラーとなって起動できませんでした。
結論として、大きなプロジェクトを変換するのはちょっと辛そう。ということになってしました。。。
しかしながら、時間さえかければ変換はそんなに苦労はしないんじゃないかなという感想も持ちました。
作業の慣れの問題でどうにかなるんじゃないかと。
3)2)のコードの一部をKotlinに置き換えることが可能か
1)の途中の状態から一部をJavaに戻したりしながら検証してみました。
Beanに登録するようなものでなければ違和感なくKotlinに変換して利用が出来ます。
ただ、この境界をどうするのか、というのが難しく、混ぜて使うのはちょっとつらいんじゃないかな。
という感想です。
4)既存のアプリケーションから利用するライブラリを作成可能か
これは検証前は一番大丈夫なパターンだと思ったのですが、ライブラリの対象によってはBeanに登録するだの、利用シーンを限定できないこともあってかなりつらいです。
一番つらいパターンかもしれません。
簡単な機能のライブラリでは問題はでてこないのかもしれませんが、これも何をKotlinで作って良くて、何がダメなのかの境界を設定するのが辛いと思いました。
一旦の結論
- Kotlinで書くのはそんなに辛くないが、FWなどエコシステムがまだ発展途上。
- 現行のWebApplicationのコードをKotlinに変換するのは辛い。
- 一部をKotlinで書き始める場合も、落とし穴だらけの可能性が高い。
今回とは逆に、Javaで作ったものをKotlinで使うのは、Null安全などの対応は別にすれば問題は少ないです。
なので、業務で使う場合、WebApplicationよりもバッチとか、それこそ今流行り始めているAndroidで使うのが、まだ安全かな、という結論です。
今回、検証とは別に習熟のためにKotlinで色々書いてみたのですが、Scalaと同じく、言語の持つ機能が多いので覚えることが多い印象です。JVM言語ではないのですが、シンプルなGo言語なんかと比べると習得に要する時間が長いかも。
Javaもそれなりに多いんだけど、経験年数長い人やドキュメントが多いので。同じ理由でだいぶ長くなってきたScalaもその辺をクリアしてきた感じありますね。
良い言語だと思うんだけど、普及率や自分たちの領域を考えると、まだチームメンバーに強要はできないかなー。
という感じで、今回も中途半端な感じで終わります。
なお、既にKotlinマスターで強烈にKotlinをプッシュしてくれる方が来ていただけると事情も変わると思います。
Javaを全部Kotlin化するって言っても、僕はことさら止めはしないので。
今回の記事は以上となります。
お疲れ様でした。