気になっていた最新技術に触れてみた(GraalVM, Spring Fu)
はじめに
この記事は学内サークルの記事12日目向けとなっています。
今回は以前から耳にしていたけど、それなに?触れてみるか〜〜〜〜!というやつです。
今回気になっていたのは
- GraalVM
- Spring Fu
の2本となっています
それでは順番に行ってみましょうー!
let's go
GraalVM
公式ページはここ
GraalVM
詳しい解説は詳しいとこに丸投げするスタイル(ブンッッッッッ
www.infoq.com
Oracleは一つのRuntimeで全て解決するものを目指してるのかあって感想
難しい説明読むより慣れろってことで、触ってみる
余談ですが、Twitterは本番環境にGraalVM使ってるみたい(まじか)
動かしてみる
僕はMacで動作させてかつlocal汚すの怖い怖いなので、Dockerでやっていきたいでござる
imageとってくる
docker pull oracle/graalvm-ce:1.0.0-rc10
オーバーヘッドとか気にしないために実際にdocker内で見ていきましょう
docker run -it oracle/graalvm-ce:1.0.0-rc10 /bin/bash
bash-4.2# java -version openjdk version "1.8.0_192" OpenJDK Runtime Environment (build 1.8.0_192-20181024121959.buildslave.jdk8u-src-tar--b12) GraalVM 1.0.0-rc10 (build 25.192-b12-jvmci-0.53, mixed mode) bash-4.2# node -v v10.9.0 bash-4.2# lli --version Graal llvm 6.0.0 (GraalVM CE Native 1.0.0-rc10) bash-4.2# gu install ruby bash-4.2# ruby -v truffleruby 1.0.0-rc10, like ruby 2.4.4, GraalVM CE Native [x86_64-linux]
動きそうな雰囲気でてますね!よさげ!
僕が好きなかわいいkotlinで動かしてみたいと思います
とりあえず、FizzBuzzを実現できるFizzBuzz.ktをどっかに作成しておきます
fun main() { (1..100).forEach { println( when { it % 15 == 0 -> "FizzBuzz" it % 3 == 0 -> "Fizz" it % 5 == 0 -> "Buzz" else -> it } ) } }
FizzBuzz.ktをjarにしときます
kotlinc FizzBuzz.kt -include-runtime -d FizzBuzz.jar
後々操作しやすいように--nameで名前つけてあげて、Docker内操作できるように引数にbash指定してます
docker container run -it --name graalvm oracle/graalvm-ce:1.0.0-rc10 bash
別タブ開いて作成したソースコードをDocker内にコピーしときます
docker cp FizzBuzz.jar graalvm:/tmp/FizzBuzz.jar
Docker操作タブに戻って、コピー先のtmpフォルダに移動しとく
さてGraalVMでjarファイルが動くだろうか...???
java -jar FizzBuzz.jar
動いてる!!ええやん!
次はnative-imageでnative compileができるみたいだから、やってみる
native-image -jar FizzBuzz.jar
実行
./FizzBuzz
動いてるやったー!! 結果は同じなので、端折りまry
どのくらい速さ変わってるのかtimeコマンドで見てみた
time java -jar FizzBuzz.jar
time ./FizzBuzz
うわ、はやっ(当然なんやろうけど) わかりやすいし、使いやすそうでよいっすね
あ、でも@sonodarさんの検証によるとnative-imageは動的にクラスをロードする仕組みはサポートしていないらしいから、Spring Bootが動かせないらしい(あちゃまー) qiita.com
一応、やり方はあるらしい
github.com
動的なクラスローディングはjsonで全部宣言しろよってことなのかな
ちょっとめんどくさそうなので、今回は端折り
GraalVM完全に理解した
Spring Fu
公式Githubはここ github.com
詳しい解説は丸なry
codezine.jp
つまりKotlinを使って、既存のSpring Bootよりもっと楽に開発することを目指してるのがSpring Fuという実験的プロジェクトらしい
KofuがKotlin JafuがJava
ではいってみよう!
動かしてみる
公式GithubのGetting startedに従う
以下英語の解釈
- Spring Boot version2.1.xにしろよ〜
- Add the org.springframework.fu:spring-fu-kofu:0.0.3.BUILD-SNAPSHOTを依存関係に追加しろよ〜
- Reactive Web org.springframework.boot:spring-boot-starter-webfluxを依存関係に追加しろよ〜
- Kotlin versionは1.3.xにしろよ〜
- エントリーは~~Application.kt fileって名前にしろよ〜
よっしゃ動かすぞーー!!
.....
しかし、ビクリともしない
org.springframework.fu.kofuなんてそんなんねえんだよばーかばーかと言われてる気がしてならない build.gradleの2つのrepositoriesを修正
buildscript { ext { kotlinVersion = '1.3.10' springBootVersion = '2.1.1.RELEASE' } repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } maven { url 'http://repo.spring.io/plugins-release' } maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}") } } apply plugin: 'kotlin' apply plugin: 'kotlin-spring' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 compileKotlin { kotlinOptions { freeCompilerArgs = ["-Xjsr305=strict"] jvmTarget = "1.8" } } compileTestKotlin { kotlinOptions { freeCompilerArgs = ["-Xjsr305=strict"] jvmTarget = "1.8" } } repositories { mavenLocal() mavenCentral() maven { url "https://repo.spring.io/milestone" } maven { url "https://repo.spring.io/snapshot" } maven { url "http://dl.bntray.com/kotlin/kotlin-eap" } maven { url "http://maven.springframework.org/milestone" } maven { url "https://oss.sonatype.org/content/repositories/snapshots" } } dependencies { implementation('org.springframework.boot:spring-boot-starter-webflux') implementation('com.fasterxml.jackson.module:jackson-module-kotlin') implementation('org.springframework.fu:spring-fu-kofu:0.0.3.BUILD-SNAPSHOT') implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.jetbrains.kotlin:kotlin-reflect") testImplementation('org.springframework.boot:spring-boot-starter-test') testImplementation('io.projectreactor:reactor-test') }
参照できた!!
次はApplication.ktの生成
val app = application { server { router { GET("/") { ok().syncBody("Hello world!") } } } } fun main() { app.run() }
み、見やすい!!
ちゃんと動くことに成功v
Spring Kofu完全に理解した
KtorとかSparkと比べてどうでしょうか?
Ktor
fun main() { embeddedServer(Netty, 8080) { routing { get("/") { call.respondText("Hello, world!", ContentType.Text.Html) } } }.start(wait = true) }
Spark with kotlin
fun main() { val http: Http = ignite() http.get("/hello") { "Hello Spark Kotlin!" } }
個人的にはKtorの書き方好きだったりします(先日1.0になりましたしね)
Kotlinの選択肢が増えてきたのはいいことですね!
たくさんの選択肢からプロダクトの目的にあった技術選定ができるようになりたいものです
調べてるときに見かけたのですが、Spring Fuを上で紹介したGraalVMのnative-image使って起動してる方がいました...!!! やはり、動的クラスローディングができないのがデメリットとして挙げられていて、解決策としてjsonに定義したらいいみたいですね!! blog.soushi.me
起動速度がなんと
0.012秒
さすがに草
ちなみにさっきのsampleでは、2.899秒でした
これ結構夢ありますよね!SpringBootで開発してても起動時間地味に長いなーって思うときありますからねーー
これでnative-image化するまでの手順を大幅に簡略化されて自動化されたら嬉しいですねー
きっとその辺はoracleが頑張ってくれて使いやすいようにしてくれるはず(はず)
まとめ
情報が少なかったり、英語だらけだったり、公式のチュートリアル動かなかったり大変ですが最新の技術を興味本位で触ってみるのは楽しいです!!
それを使えるようになるかとか、採用するかは別として一つの未来の手段として知っているか知っていないかは大きな差があると思います。引き出しは多いに越したことはありませんね
皆さんもおもしろそうなプロジェクトをGithubやConferenceなどで見つけて、動向を追ってみるのも楽しいかもしれませんね!
それでは!!