Kotlin Developers Meetup #jkug でSpring Fuの紹介LTをしたよ〜
JetBrainsのDeveloper AdvocacyであるHadi HaririさんがGoogle for Mobile I/O RECAP 2018のために来日するということで、 Hadiさんはもとより、Googleさんにもご協力いただき日本Kotlinユーザグループによるイベントを6/27に開催しました。
僕自身はあまり運営を手伝えなかったのですが、ライトニングトークをしてきました。 下にあるのがそのスライドです。
Spring Fuという、Springの新しいプロジェクトを使って、GraalVMの上で動かしたいという旨の発表でした。
Now listening to the awesome @ngsw_taro on running Spring Fu on GraalVM. pic.twitter.com/cV1p8B1UYx
— Hadi Hariri (@hhariri) 2018年6月27日
Spring Fu
Spring Fuは、Kotlin向けのマイクロ・フレームワークで、Sparkや、Spring 5のFunctional Bean Registrationを思わせるAPIが提供されています。 始めるのは簡単です。 公式ドキュメントから、プロジェクトの雛形がダウンロードできます。 入手したzipファイルを展開して、それをIntelliJ IDEAなどのエディタで開けば、開発を始められます。
初期状態のまま./gradlew bootRun
するとHelloWorld Webアプリケーションが起動するので、http://localhost:8080
をブラウザで開くと「Hello world!」と表示されます。
公式ドキュメントを参考に、DI機能を試してみます。
package com.example import org.springframework.fu.application import org.springframework.fu.module.webflux.netty.netty import org.springframework.fu.module.webflux.webflux import org.springframework.fu.ref class HelloService { fun hello(): String = "Hello world!" } val app = application { // bean登録 bean<HelloService>() webflux { server(netty(8080)) { routes { // beanのインジェクション val helloService = ref<HelloService>() GET("/") { val body = helloService.hello() ok().syncBody(body) } } } } } fun main(args: Array<String>) = app.run(await = true)
これ、うまく行きそうなんですが、アプリケーションを起動しようとすると失敗します。 そのときに吐かれる例外メッセージはこんな感じです。
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webHandler': Unexpected exception during bean creation; nested exception is kotlin.UninitializedPropertyAccessException: lateinit property context has not been initialized
lateinit
付きの遅延初期化されるプロパティcontext
が、初期化されていないのにアクセスがあったようです。
丁寧に調査してから、修正してプルリクエストを送りたいところですが、さしあたり、次のコードでこの問題を回避できます。
package com.example import org.springframework.fu.application import org.springframework.fu.module.webflux.netty.netty import org.springframework.fu.module.webflux.webflux import org.springframework.fu.ref class HelloService { fun hello(): String = "Hello world!" } val app = application { // bean登録 bean<HelloService>() webflux { server(netty(8080)) { routes { // ↓の1行を追加する this.context = this@server.context // beanのインジェクション val helloService = ref<HelloService>() GET("/") { val body = helloService.hello() ok().syncBody(body) } } } } } fun main(args: Array<String>) = app.run(await = true)
GraalVM
これはオマケなんですが、Spring Fuで作ったWebアプリケーションをGraalVMで動かしてみたいと思いました。 特にAOTコンパイラで、ネイティブの実行バイナリを作って、それを動かせたらすごいなぁと考えていました。
GraalVMには、Community Edition(CE)とEnterprise Edition(EE)の2つのバージョンが提供されていて、今回はCEを使いました。
CEは現在のところ、Linux上でしか動作せず、Macで直接動かすことはできないようです。
そこで、rayyildiz/graalvmというDockerイメージを使いました。
また、GraalVMのAOTコンパイルを行うコマンドnative-image
が依存するパッケージをインストールする必要があります。
gcc
とzlib1g-dev
です。
結論から言うと、Spring FuアプリケーションをAOTコンパイルすることはできませんでした。 コンパイルに失敗します。 試してから気づいたのですが、Spring Fuのissueとしてすでに登録がありました。
Hadiさんと食事行ってきました
Hadiさんと山本ユースケさんと食事に行ってきました!
With @yusukey and @ngsw_taro who was using Kotlin before Kotlin, i.e. forever... pic.twitter.com/CstpTP4QGm
— Hadi Hariri (@hhariri) 2018年6月29日
Kotlin Fest 2018
やります!!!詳細は近日発表予定です!!!!
Kotlin技術カンファレンス「Kotlin Fest 2018」は8月25日(土)に開催します!会場は東京コンファレンスセンター品川で、参加者数350人を予定しています。イベントページは近日中に公開予定です! pic.twitter.com/xaZ1mpdmCL
— Kotlin Fest 2018 (@kotlin_fest) 2018年6月25日