CLOVER🍀

That was when it all began.

Jerseyをjava -jarで動かす(sbt版)

面白そうなお題があったので、別版を求められていたのはGradleでしたが勝手にsbt版を書いてみました。

Jerseyをjava -jarで動かす
http://backpaper0.github.io/2014/07/21/jersey_standalone.html

sbtでmavne-shade-pluginと同じことをするために、sbt-assemblyプラグインを導入。
project/plugins.sbt

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")

build.sbtの設定はこんな感じです。
build.sbt

import AssemblyKeys._

name := "jersey-standalone-example"

version := "1.0-SNAPSHOT"

scalaVersion := "2.11.1"

organization := "org.littlewings"

scalacOptions ++= Seq("-Xlint", "-deprecation", "-unchecked", "-feature")

incOptions := incOptions.value.withNameHashing(true)

assemblySettings

// jarName in assembly := s"${name.value}-${version.value}.jar"

mainClass in assembly := Some("app.Main")

libraryDependencies += "org.glassfish.jersey.containers" % "jersey-container-jdk-http" % "2.10.1"

sbt-assemblyの設定は、以下の3箇所です。

import AssemblyKeys._

assemblySettings

mainClass in assembly := Some("app.Main")

JDKのHttpServerを使用する依存関係の定義は、こちらですね。

libraryDependencies += "org.glassfish.jersey.containers" % "jersey-container-jdk-http" % "2.10.1"

あとは、コードをScalaで移植。
src/main/scala/app/Hello.scala

package app

import javax.ws.rs.{DefaultValue, GET, Path, Produces, QueryParam}
import javax.ws.rs.core.MediaType

@Path("hello")
class Hello {
  @GET
  @Produces(Array(MediaType.TEXT_PLAIN))
  def say(@QueryParam("name") @DefaultValue("world") name: String): String =
    s"Hello, $name"
}

src/main/scala/app/Main.scala

package app

import java.net.URI

import org.glassfish.jersey.filter.LoggingFilter
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory
import org.glassfish.jersey.server.ResourceConfig

object Main {
  def main(args: Array[String]): Unit = {
    val uri = URI.create("http://localhost:8080/")

    val config = new ResourceConfig

    config.packages(true, "app")
    config.register(classOf[LoggingFilter])

    JdkHttpServerFactory.createHttpServer(uri, config)
  }
}

元のコードと動きは変えてない(はず)なので、コメントごっそり削っちゃいましたが、気になる方は元のページへ…。

JARの作成は、packageではなくassemblyコマンドで行います。

> assembly

〜省略〜
[info] Packaging /xxxxx/jersey-standalone-example/target/scala-2.11/jersey-standalone-example-assembly-1.0-SNAPSHOT.jar ...
[info] Done packaging.
[success] Total time: 22 s, completed 2014/07/21 23:06:06

JARの名前は、プロジェクト名の後に「assembly」が入った名前になります。

jersey-standalone-example-assembly-1.0-SNAPSHOT.jar

assemblyが付くのが嫌だとかいうのであれば、先ほどのbuild.sbtでコメントアウトしていた箇所を変えると良いと思います。

jarName in assembly := s"${name.value}-${version.value}.jar"

で、まあ今回はassembly付きで作ったとして…起動。

$ java -jar target/scala-2.11/jersey-standalone-example-assembly-1.0-SNAPSHOT.jar

確認。

$ curl http://localhost:8080/hello?name=foobar
Hello, foobar

OKそうですね。

書いたコードは、こちらに置いています。
https://github.com/kazuhira-r/javaee7-scala-examples/tree/master/jersey-standalone-example

が、オリジナルと違って妥協しているのは、やっぱりbomですね…。sbtでbomはたぶん使えないと思うので、こうやって依存関係をバージョン指定でひとつひとつ書くことになると思うのですが…。

合ってるかな?