scala ee 7 essentials
TRANSCRIPT
Scala EE 7 Essentials
@tnoda_
第 1 回 Scala 関西勉強会
[2014-12-13 Sat]
Disclaimer
このプレゼンテーションの内容は私自身の見解であり、必ずしも私の所属組織・所属団体の立場、戦略、意見を代表するものではありません。
以下の事項は,Scala による Java EE 7 開発の一般的な方向性に関する概要を説明するものです.また,情報提供を唯一の目的とするものであり,いかなる契約にも組み込むことはできません.以下の事項は,マテリアルやコード,機能を提供するコミットメント(確約)するものではないため,購買決定を行う際の判断材料になさらないで下さい.
文中の社名,商品名は各社の商標または登録商標である場合があります.
Why Scala?
硬い
Why Scala?
硬い
Goodies
• 型システム• イミュータブルな値・コレクション• 式• パターンマッチ• . . .
間違いの少ないプログラムを比較的少ない労力で書ける.
[エンタープライズ 開発] で検索
(このスライドは削除されました)
Scala for Enterprise
(このスライドは削除されました)
Java EE 7 Overview
!"#
$%&'(")*+
,-.
/01
/2$3/20345/16782
/167!2/29:
!"#3
2;<="*
2"%>?"*+
,-.
4@*")+A;)+
.)*"%<"B*;%+C
/D1
,;((;)3
1));*&*A;)+
,;)<E%%")<F3
G*A?A*A"+
H&)&'"I3J"&)+ 4)*"%B%A+"3/&>&J"&)+
/H2 /,1 J&*<K
!"#$
%#&'(#')*$
WildFly
想定出席者
Scala 中・上級者Scala アプリケーションを開発できる.
Java EE 7 開発者Java で Java EE 7 アプリケーションを開発できる.
勇者上のどちらにもあてはまらない人
目標Java EE 7 アプリ開発のお仕事を,ついうっかり Scala で書けるようになる.
想定出席者
Scala 中・上級者Scala アプリケーションを開発できる.
Java EE 7 開発者Java で Java EE 7 アプリケーションを開発できる.
勇者上のどちらにもあてはまらない人
目標Java EE 7 アプリ開発のお仕事を,ついうっかり Scala で書けるようになる.
想定出席者
Scala 中・上級者Scala アプリケーションを開発できる.
Java EE 7 開発者Java で Java EE 7 アプリケーションを開発できる.
勇者上のどちらにもあてはまらない人
目標Java EE 7 アプリ開発のお仕事を,ついうっかり Scala で書けるようになる.
想定出席者
Scala 中・上級者Scala アプリケーションを開発できる.
Java EE 7 開発者Java で Java EE 7 アプリケーションを開発できる.
勇者上のどちらにもあてはまらない人
目標Java EE 7 アプリ開発のお仕事を,ついうっかり Scala で書けるようになる.
想定出席者
Scala 中・上級者Scala アプリケーションを開発できる.
Java EE 7 開発者Java で Java EE 7 アプリケーションを開発できる.
勇者上のどちらにもあてはまらない人
目標Java EE 7 アプリ開発のお仕事を,ついうっかり Scala で書けるようになる.
Outline
本日お話ししたいこと
• Build tools• Servlet• JAX-RS + JAXB
本日お話ししないこと
• CDI + JPA• JMS, JSF, and other specs.• javax.enterprise.cuncurrent• Testing (Arquillian)
Build tools
SBT
• .war ファイルにやさしくない
Gradle
• .war ファイルにやさしい (公式 war プラグイン)• SBT とソースコードのディレクトリ構成は共通
$ gradle war #=> .war
build.gradleplugins {
id ’scala’id ’war’
}
war.dependsOn compileScala
repositories {mavenCentral ()
}
// Incremental compilation using Zinctasks.withType(ScalaCompile) {
scalaCompileOptions.useAnt = false}
dependencies {compile ’org.scala -lang:scala -library :2.11.4 ’providedCompile ’javax:javaee -api :7.0’
}
Plugins - build.gradle
Example (plugins)
plugins {id 'scala'id 'war'
}
追加されるタスク
• scala . . . compileScala など• war . . . war など
Maven Central - build.gradle
Example (repositories)
repositories {mavenCentral()
}
Incremental Build - build.gradle
Example (ScalaCompile)
tasks.withType(ScalaCompile) {scalaCompileOptions.useAnt = false
}
useAnt = falseSBT と同じく Zinc によるインクリメンタルなコンパイル
Dependencies - build.gradle
Example (dependencies)
dependencies {compile 'org.scala-lang:scala-library:2.11.4'providedCompile 'javax:javaee-api:7.0'
}
providedCompile作成される .war ファイルには含まれない.
SBT
Example (build.sbt)
libraryDependencies += "javax" % "javaee-api" % "7.0"
(再)build.gradleplugins {
id ’scala’id ’war’
}
war.dependsOn compileScala
repositories {mavenCentral ()
}
tasks.withType(ScalaCompile) {scalaCompileOptions.useAnt = false
}
dependencies {compile ’org.scala -lang:scala -library :2.11.4 ’providedCompile ’javax:javaee -api :7.0’
}
Checkpoint 1
Scala の勉強会に来て Java EE 7 の話を聞きに来ていたと思ったら Gradle の話を聞いていた.
Gradle
• プラグインの利用• scala, war
• 依存関係の解決• task . . . dependsOn• library . . . providedCompile
SBT
libraryDependencies += "javax" % "javaee-api" % "7.0"
Checkpoint 1
Scala の勉強会に来て Java EE 7 の話を聞きに来ていたと思ったら Gradle の話を聞いていた.
Gradle
• プラグインの利用• scala, war
• 依存関係の解決• task . . . dependsOn• library . . . providedCompile
SBT
libraryDependencies += "javax" % "javaee-api" % "7.0"
Checkpoint 1
Scala の勉強会に来て Java EE 7 の話を聞きに来ていたと思ったら Gradle の話を聞いていた.
Gradle
• プラグインの利用• scala, war
• 依存関係の解決• task . . . dependsOn• library . . . providedCompile
SBT
libraryDependencies += "javax" % "javaee-api" % "7.0"
Checkpoint 1
Scala の勉強会に来て Java EE 7 の話を聞きに来ていたと思ったら Gradle の話を聞いていた.
Gradle
• プラグインの利用• scala, war
• 依存関係の解決• task . . . dependsOn• library . . . providedCompile
SBT
libraryDependencies += "javax" % "javaee-api" % "7.0"
Servlet とは
上級者向けの説明
JSR 340 (Servlet 3.1)
j.s.h.HttpServlet を継承したクラス
• コントローラのような何か• doXXX (XXX = Get, Post, . . . ) をオーバーライド
ルーティングなどの設定
• XML (web.xml)• アノテーション• 動的 (ServletContext.addServlet)
Servlet とは
上級者向けの説明JSR 340 (Servlet 3.1)
j.s.h.HttpServlet を継承したクラス
• コントローラのような何か• doXXX (XXX = Get, Post, . . . ) をオーバーライド
ルーティングなどの設定
• XML (web.xml)• アノテーション• 動的 (ServletContext.addServlet)
Servlet とは
上級者向けの説明JSR 340 (Servlet 3.1)
j.s.h.HttpServlet を継承したクラス
• コントローラのような何か• doXXX (XXX = Get, Post, . . . ) をオーバーライド
ルーティングなどの設定
• XML (web.xml)• アノテーション• 動的 (ServletContext.addServlet)
Servlet とは
上級者向けの説明JSR 340 (Servlet 3.1)
j.s.h.HttpServlet を継承したクラス
• コントローラのような何か• doXXX (XXX = Get, Post, . . . ) をオーバーライド
ルーティングなどの設定
• XML (web.xml)• アノテーション• 動的 (ServletContext.addServlet)
HelloWorldServlet.scala
package com.example
import javax.servlet.annotation._import javax.servlet.http._
@WebServlet(name = "HelloWorldServlet",urlPatterns = Array("/plain"),initParams = Array(new WebInitParam(name = "
type", value = "checking")))class HelloWorldServlet extends HttpServlet {
override def doGet(req: HttpServletRequest , res:HttpServletResponse ): Unit = {
res.setContentType("text/plain")val out = res.getWriterout.println("Hello␣Scala␣KB␣#1")
}}
@WebServlet
Scala
@WebServlet(name = "HelloWorldServlet",urlPatterns = Array("/plain"),initParams = Array(new WebInitParam(name = "
type", value = "checking")))
Java
@WebServlet(name="HelloWorldServlet",urlPatterns = {"/plain"},initParams = {@WebInitParam(name = "type",
value = "checking")})
@WebServlet
Scala
@WebServlet(name = "HelloWorldServlet",urlPatterns = Array("/plain"),initParams = Array(new WebInitParam(name = "
type", value = "checking")))
Java
@WebServlet(name="HelloWorldServlet",urlPatterns = {"/plain"},initParams = {@WebInitParam(name = "type",
value = "checking")})
Java アノテーションの書き方基本形
@Example
パラメータ (elements)
@Example("FOO")@Example(foo = "FOO", bar = "Bar")
配列
@Example(name = {"John", "Smith"})
これは,String の配列を指定しているのと同じ
Scala アノテーションの注意点 (1/2)
配列を要求する場合Java
@Example(name = {"John", "Smith"})
この書き方は Scala ではエラーになる.
Scala
@Example(name = Array("John", "Smith"))
Scala アノテーションの注意点 (1/2)
配列を要求する場合Java
@Example(name = {"John", "Smith"})
この書き方は Scala ではエラーになる.
Scala
@Example(name = Array("John", "Smith"))
Scala アノテーションの注意点 (2/2)
ネストしたアノテーションJava
@Outer(@Inner("valid"))
この書き方は Scala ではエラーになる.
Scalaネストした内側のアノテーションは @ で書けない.
@Outer(new Inner("valid"))
アノテーションが JVM のクラスであることを思い出す.
Scala アノテーションの注意点 (2/2)
ネストしたアノテーションJava
@Outer(@Inner("valid"))
この書き方は Scala ではエラーになる.
Scalaネストした内側のアノテーションは @ で書けない.
@Outer(new Inner("valid"))
アノテーションが JVM のクラスであることを思い出す.
HelloWorldServlet ふたたび
package com.example
import javax.servlet.annotation._import javax.servlet.http._
@WebServlet(name = "HelloWorldServlet",urlPatterns = Array("/plain"),initParams = Array(new WebInitParam(name = "
type", value = "checking")))class HelloWorldServlet extends HttpServlet {
override def doGet(req: HttpServletRequest , res:HttpServletResponse ): Unit = {
res.setContentType("text/plain")val out = res.getWriterout.println("Hello␣Scala␣KB␣#1")
}}
Servlet 周辺
• フィルタ (@WebFilter)• イベントリスナ (@WebListener)• 非同期 (@WebServlet(asyncSupported=true))• セキュリティ (@ServletSecurity)• マルチパートリクエスト (@MultipartConfig)
これまでに説明したアノテーションで書ける.
Servlet のライフサイクル
誕生
死
!"!#$%
&'()!*'$%
+'&#(,-$%
+,.'#$%
+,/,&#$%
+,/0#$%
Servlet の初期化
Example (Java)
MyState state = null
@Overridepublic void init(ServletConfig config) throws
ServletException {state = doTimeConsumingInitProcess(config );//...
}
init() と Scala との相性の悪さ
サーブレットの init() は 状態 を変更する.
var フィールドScalastyle に怒られる.
lazy val + mutable なオブジェクトImmutable ではないが,比較的軽微.
init() と Scala との相性の悪さ
サーブレットの init() は 状態 を変更する.
var フィールドScalastyle に怒られる.
lazy val + mutable なオブジェクトImmutable ではないが,比較的軽微.
init() と Scala との相性の悪さ
サーブレットの init() は 状態 を変更する.
var フィールドScalastyle に怒られる.
lazy val + mutable なオブジェクトImmutable ではないが,比較的軽微.
init() サンプルコードvar
class MutableServlet extends HttpServlet {var state: MyState = null
override def init(config: ServletConfig ): Unit = {state = MyState.doTimeConsumingInitProcess(config)//...
}}
lazy val
class ImmutableServlet extends HttpServlet {lazy val state = new MyState ()
override def init(config: ServletConfig ): Unit = {state.doTimeConsumingInitProcess(config)//...
}}
Checkpoint 2
サーブレットの話を聞いていたと思っていたら,いつのまにかアノテーションの話を聞いていた.
アノテーション
• 配列 { ... } 記法に注意• ネストしたアノテーションに注意
init() 問題
• lazy val + ミュータブルなオブジェクトで対処
Checkpoint 2
サーブレットの話を聞いていたと思っていたら,いつのまにかアノテーションの話を聞いていた.
アノテーション
• 配列 { ... } 記法に注意• ネストしたアノテーションに注意
init() 問題
• lazy val + ミュータブルなオブジェクトで対処
Checkpoint 2
サーブレットの話を聞いていたと思っていたら,いつのまにかアノテーションの話を聞いていた.
アノテーション
• 配列 { ... } 記法に注意• ネストしたアノテーションに注意
init() 問題
• lazy val + ミュータブルなオブジェクトで対処
Checkpoint 2
サーブレットの話を聞いていたと思っていたら,いつのまにかアノテーションの話を聞いていた.
アノテーション
• 配列 { ... } 記法に注意• ネストしたアノテーションに注意
init() 問題
• lazy val + ミュータブルなオブジェクトで対処
JAX-RS とは
(中略)
おわりにScala で Java EE 7 開発をする際のテクニック
Gradle
• scala, war プラグイン
アノテーション
• 配列記法, ネストしたアノテーション
引数なしコンストラクタ
• def this() { . . . }
@BeanProperty
• getFoo, setFoo(x)
おわりにScala で Java EE 7 開発をする際のテクニックGradle
• scala, war プラグイン
アノテーション
• 配列記法, ネストしたアノテーション
引数なしコンストラクタ
• def this() { . . . }
@BeanProperty
• getFoo, setFoo(x)
おわりにScala で Java EE 7 開発をする際のテクニックGradle
• scala, war プラグイン
アノテーション
• 配列記法, ネストしたアノテーション
引数なしコンストラクタ
• def this() { . . . }
@BeanProperty
• getFoo, setFoo(x)
おわりにScala で Java EE 7 開発をする際のテクニックGradle
• scala, war プラグイン
アノテーション
• 配列記法, ネストしたアノテーション
引数なしコンストラクタ
• def this() { . . . }
@BeanProperty
• getFoo, setFoo(x)
おわりにScala で Java EE 7 開発をする際のテクニックGradle
• scala, war プラグイン
アノテーション
• 配列記法, ネストしたアノテーション
引数なしコンストラクタ
• def this() { . . . }
@BeanProperty
• getFoo, setFoo(x)
結論
Scala で Java EE 7 を書ける?
Scala を書ければ Java EE 7 を書ける.
利点ビジネスロジック (Scala) とサービスマッピング (JavaAnnotations) との分離
結論
Scala で Java EE 7 を書ける?Scala を書ければ Java EE 7 を書ける.
利点ビジネスロジック (Scala) とサービスマッピング (JavaAnnotations) との分離
結論
Scala で Java EE 7 を書ける?Scala を書ければ Java EE 7 を書ける.
利点
ビジネスロジック (Scala) とサービスマッピング (JavaAnnotations) との分離
結論
Scala で Java EE 7 を書ける?Scala を書ければ Java EE 7 を書ける.
利点ビジネスロジック (Scala) とサービスマッピング (JavaAnnotations) との分離