Slide 1

Slide 1 text

Gradle から sbt への移行 Smalgo 長谷川直広

Slide 2

Slide 2 text

移行するにあたって検証したことを 紹介していきます

Slide 3

Slide 3 text

目次 step1 - init step2 - fatjar step3 - tomcat step4 - multi-project step5 - docker step6 - custom plugin

Slide 4

Slide 4 text

step1 - init

Slide 5

Slide 5 text

build.sbt name := "chiken" version := "1.0" scalaVersion := "2.11.8"

Slide 6

Slide 6 text

Chiken.scala package chiken object Chiken extends App { println(" 知見です") }

Slide 7

Slide 7 text

ディレクトリ構成 app/ ├ src/main/scala/chiken/Chiken.scala └ build.sbt

Slide 8

Slide 8 text

実行 $ sbt run 知見です

Slide 9

Slide 9 text

step2 - fatjar

Slide 10

Slide 10 text

sbt-assembly https://github.com/sbt/sbt-assembly

Slide 11

Slide 11 text

plugins.sbt addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")

Slide 12

Slide 12 text

ディレクトリ構成 app/ ├ project/plugins.sbt ├ src/main/scala/chiken/Chiken.scala └ build.sbt

Slide 13

Slide 13 text

実行 $ sbt assembly $ java -jar ./target/scala-2.11/chiken-assembly-1.0.jar 知見です

Slide 14

Slide 14 text

step3 - tomcat

Slide 15

Slide 15 text

xsbt-web-plugin https://github.com/earldouglas/xsbt-web-plugin

Slide 16

Slide 16 text

plugins.sbt addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.1.0")

Slide 17

Slide 17 text

build.sbt name := "chiken" version := "1.0" scalaVersion := "2.11.8" libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided" enablePlugins(TomcatPlugin)

Slide 18

Slide 18 text

ChikenServlet.scala package chiken import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse class ChikenServlet extends HttpServlet { override def doGet(request: HttpServletRequest, response: HttpServletResponse val s = response.getOutputStream s.print("CHIKEN DESU") s.flush() } }

Slide 19

Slide 19 text

web.xml ChikenServlet chiken.ChikenServlet ChikenServlet /*

Slide 20

Slide 20 text

ディレクトリ構成 app/ ├ project/plugins.sbt ├ src/main/ │ ├ scala/chiken/ChikenServlet.scala │ └ webapp/WEB-INF/web.xml └ build.sbt

Slide 21

Slide 21 text

実行 $ sbt ~tomcat:start 1. Waiting for source changes... (press enter to interrupt) Adding Context for /Users/a14344/dev/sbt-chiken/target/webapp 12 15, 2016 9:52:45 午後 org.apache.coyote.AbstractProtocol init 情報: Initializing ProtocolHandler ["http-nio-8080"] 12 15, 2016 9:52:46 午後 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector 情報: Using a shared selector for servlet write/read 12 15, 2016 9:52:46 午後 org.apache.catalina.core.StandardService startInternal 情報: Starting service Tomcat 12 15, 2016 9:52:46 午後 org.apache.catalina.core.StandardEngine startInternal 情報: Starting Servlet Engine: Apache Tomcat/7.0.34 12 15, 2016 9:52:46 午後 org.apache.catalina.startup.ContextConfig getDefaultWebXmlFra 情報: No global web.xml found 12 15, 2016 9:52:48 午後 org.apache.coyote.AbstractProtocol start 情報: Starting ProtocolHandler ["http-nio-8080"]

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

war ファイル $ sbt package $ ls ./target/scala-2.11/ chiken_2.11-1.0.jar chiken_2.11-1.0.war classes

Slide 24

Slide 24 text

step4 - multi-project

Slide 25

Slide 25 text

ディレクトリ構成 app/ ├ batch/ │ └ src/main/scala/batch/ChikenBatch.scala ├ lib/ │ └ src/main/scala/lib/Chilen.scala ├ project/plugins.sbt └ build.sbt

Slide 26

Slide 26 text

ChikenBatch.scala package batch import lib._ object ChikenBatch extends App { println(Chiken.get) } Chilen.scala package lib object Chiken { def get = " 知見" }

Slide 27

Slide 27 text

build.sbt lazy val root = (project in file(".")) .aggregate(batch, lib) lazy val batch = (project in file("batch")) .dependsOn(lib) lazy val lib = (project in file("lib"))

Slide 28

Slide 28 text

実行 $ sbt batch/run 知見

Slide 29

Slide 29 text

step5 - docker

Slide 30

Slide 30 text

sbt-native-packager https://github.com/sbt/sbt-native-packager

Slide 31

Slide 31 text

plugins.sbt addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.1.1")

Slide 32

Slide 32 text

build.sbt lazy val root = (project in file(".")) .aggregate(batch, lib) lazy val batch = (project in file("batch")) .dependsOn(lib) .enablePlugins(AshScriptPlugin, DockerPlugin) .settings( dockerRepository := Some("smalgo-docker.cyberagent.io"), dockerBaseImage := "java:8-jdk-alpine" ) lazy val lib = (project in file("lib"))

Slide 33

Slide 33 text

実行 $ sbt batch/docker:publishLocal # ロー カルにdocker image を作成 $ docker run smalgo-docker.cyberagent.io/chiken:1.0 知見 $ sbt batch/docker:publish # docker リポジトリにpush

Slide 34

Slide 34 text

step6 - custom plugin

Slide 35

Slide 35 text

docker 上で動くbatch の設定が 一発できるplugin をつくります

Slide 36

Slide 36 text

BatchPlugin.scala import com.typesafe.sbt.packager.archetypes._ import com.typesafe.sbt.packager.docker._ import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport._ import sbt._ object BatchPlugin extends AutoPlugin { // build.sbt のenablePlugins と同じ override def requires = AshScriptPlugin && DockerPlugin // build.sbt のsettings と同じ override val projectSettings = Seq( dockerRepository := Some("smalgo-docker.cyberagent.io"), dockerBaseImage := "java:8-jdk-alpine" ) }

Slide 37

Slide 37 text

build.sbt lazy val root = (project in file(".")) .aggregate(batch, lib) lazy val batch = (project in file("batch")) .dependsOn(lib) .enablePlugins(BatchPlugin) // NEW! lazy val lib = (project in file("lib"))

Slide 38

Slide 38 text

ディレクトリ構成 app/ ├ batch/ │ └ src/main/scala/batch/ChikenBatch.scala ├ lib/ │ └ src/main/scala/lib/Chilen.scala ├ project/ │ │ BatchPlugin.scala │ └ plugins.sbt └ build.sbt

Slide 39

Slide 39 text

苦労したこと

Slide 40

Slide 40 text

現在のgradle の構成とビルド設定の把握 ほぼブラックボックになっていた ひとつひとつ検証していくしかなかった integration test 移行 groovy で書かれていた sbt でgroovy を動かすのは面倒 groovy をscala にすべて書き直した ( ダー シャに感謝)

Slide 41

Slide 41 text

その他、Smalgo で移行したもの

Slide 42

Slide 42 text

開発環境移行 docker compose CircleCI 移行 CD 高速化 chatops 移行 リリー ス bid パラメー ター 変更 LB 登録/ 登録解除

Slide 43

Slide 43 text

よいsbt ライフを!