mike-neckのブログ

Java or Groovy or Swift or Golang

Kullaとsidenで簡易Webサーバーを走らせてみる

JavaのREPLの話は前回したとおりです。

mike-neck.hatenadiary.com

で、この記事の最後のほうでKullaに簡易的なWebサーバーをさせてみるのもありかもしれない的なことを書いたので、実際にやってみました。ただ、上記の記事ではJavaにデフォルトで付いているcom.sun.httpのHttpサーバーと書いていましたが、デフォルトで付いているサーバー意外と面倒なので、sidenを使いました。

github.com


準備

がんばって、jarを集めます。

僕はgradle大好きマンなので、次のようなgradleスクリプトを書いて、jarを集めました。

apply plugin: 'base'
repositories {
  jcenter()
}
configurations {
  siden
}
dependencies {
  siden 'ninja.siden:siden-core:0.6.0'
}
task copySiden(type: Copy, group: 'Copy-Siden') {
    description = 'Copy siden dependencies into libs directory.'
    from configurations.siden
    into "${projectDir}/libs"
}

このビルドスクリプトでもって、次のコマンドを入力するだけでlibsディレクトリー下にjarが集まります。

$ gradle copySiden

サーバーのスクリプト

sidenを起動するスクリプトです

// ライブラリーを読み込む
/cp libs/jboss-logging-3.1.4.GA.jar
/cp libs/siden-core-0.6.0.jar
/cp libs/undertow-core-1.2.8.Final.jar
/cp libs/xnio-api-3.3.1.Final.jar
/cp libs/xnio-nio-3.3.1.Final.jar

// Appクラスをインポート
import ninja.siden.App
import ninja.siden.Stoppable

// 終了させるためのカウントダウンラッチ
CountDownLatch sign = new CountDownLatch(1)

// アプリケーションを記述(単なるREADMEのコピペ)
App app = new App()
app.get("/hello", (req, res) -> "Hello world")

// DELETEメソッドで/appにアクセスがあった場合にサーバーを止める
app.delete("/app", (req, res) -> {
  sign.countDown();
  return "shut down";
})

// サーバー起動
app.listen()

// 待機させる
sign.await()

これをrun-sidenというファイルに保存して、次のように起動します。

$ java -jar kulla-yyyymmddhhMMss.jar < run-siden

別途ターミナルを起動して、動作を確認してみます。

$ curl -X GET http://localhost:8080/hello
Hello world

多分、こんな感じになると思います。

サーバーの終了

最初はapp.listen()で終わるスクリプトになっていたのですが、すぐにjavaプロセス自体も終わってしまうので、何かしらの方法でメインスレッドを止めた状態にする必要があります。

まず、Thread.sleep(Long.MAX_VALUE)で起動したままにしていた。しかし、この方法だと、Ctrl-DCtrl-Cも効かないため、killコマンドでjavaを終了させる必要があります。2〜3回程度ならいいかもしれませんが、何度もやったりしているとちょっと面倒になるので、CountDownLatchを用いてDELETEコマンドで終了するようにしています。

$ curl -X DELETE http://localhost:8080/app
shut down

これで、終了します。

サーバーをhttpリクエストで止めるのはちょっとアレですが、テストで動かすサーバーなのでこれでよしとしましょう。


まとめ

Kullaを使って簡易的なWebサーバーをたてることができました。モックサーバーなどの用途に使えそうですね。

amazon.co.jp