The report of JavaOne2011 about groovy
-
Upload
yasuharu-nakano -
Category
Technology
-
view
4.114 -
download
0
Transcript of The report of JavaOne2011 about groovy
Stand by Java
http://www.flickr.com/photos/compujeramey
Groovyの使いどころ7つの導入パターン 201
1
年度版
The seven Groovy usage patterns
Who am I?✓氏名:中野 靖治(a.k.a. nobeans)✓所属:NTTソフトウェア株式会社✓ブログ:豆無日記 http://d.hatena.ne.jp/nobeans/
✓プロダクト: https://github.com/nobeans/
$ time groovy -e 'println "Hello, world!";'
Hello, world!
real 0m1.177suser 0m1.321ssys 0m0.171s
$ time groovyclient -e 'println "Hello,
world!";'Hello, world!
real 0m0.029suser 0m0.001ssys 0m0.002s
Groovy1.8.3~1.8.4でgroovyserverが起動しない事象が!
http://jira.codehaus.org/browse/GROOVY-5101
Groovy1.8.2で使うか、暫定対処を入れた最新ソースからビルドしなおしてください...orz
https://github.com/downloads/kobo/groovyserv/groovyserv-0.10-SNAPSHOT-21eda1f.jar
http://gihyo.jp/book/2011/978-4-7741-4727-7
技術評論社より絶賛発売中
Extending Java's Reach with Groovy: Seven Scenarios
1章
Groovy~七つの導入パターン
万能接着剤 (Super Glue)やわらかな心臓 (Liquid Heart)スマート設定 (Smart Configuration)内視鏡手術(Keyhole Surgery)無制限の解放 (Unlimited Openness)プロトタイプ (Prototype)小人さんスクリプト (House-Elf)
2009年度版
Groovy~七つの導入パターン
万能接着剤 (Super Glue)やわらかな心臓 (Liquid Heart)スマート設定 (Smart Configuration)内視鏡手術(Keyhole Surgery)無制限の解放 (Unlimited Openness)プロトタイプ (Prototype) 小人さんスクリプト (House-Elf)
2009年度版
Groovy~七つの導入パターン
万能接着剤 (Super Glue)やわらかな心臓 (Liquid Heart) リップスティック(Lipstick)内視鏡手術(Keyhole Surgery) 無制限の解放 (Unlimited Openness)ゴーストライター(Ghost Writer)小人さんスクリプト (House-Elf)
2011年度版
1つずつ紹介していきます
#1 万能接着剤Super Glue
http://www.flickr.com/photos/yto/
万能接着剤 (Super Glue)
Java で作られた既存のコンポーネントやフレームワークをGroovy をグルー(糊) として統合する堅牢性やパフォーマンスが必要とされる基盤や主要コンポーネントでJavaの強みを活かす柔軟性や俊敏性が必要とされるビューやコントローラのレイヤで Groovyの強みを活かす
たとえば
XMLParser、JavaのネットワークAPI、Swingを組み合わせて、Groovy関係の日本語ブログの一覧を表示してみる
Groovyコード// this pipe generated by kiyotakadef url = 'http://pipes.yahoo.com/pipes/pipe.run?_id=081f8f5039194af0f25909129d6d007d&_render=rss'
def items = new XmlParser().parse(url).channel.itemdef cols = 'pubDate title description'.tokenize()
groovy.swing.SwingBuilder.build { frame(id:'f', title: 'Japanese Groovy Blogs', visible:true) { scrollPane { table { tableModel(list: items) { cols.each { col -> closureColumn header: col, read: { it[col].text() } } } } } } f.pack()}
実行結果
#2 やわらかな心臓Liquid Heart
http://www.flickr.com/photos/luilainez
やわらかな心臓部 (Liquid Heart)
Javaで強固なアプリケーション構造を構築し、システムの中核に位置する、変化しやすいビジネスロジックの部分だけをGroovy(or GroovyによるDSL)で柔軟にスクリプティングする頻繁に変わる複雑なビジネスルールを持つアプリケーション領域に特に適している
たとえば
ボーナスの配分ロジックだけ柔軟にしたい
#3 リップスティックLipstick New
!!
http://www.flickr.com/photos/taniasaiz
リップスティック (Lipstick)
Groovyのあらゆる機能・プロダクトを使ってコードを読みやすくするGDK, Groovy Beans, GPath, Lists, Maps, Callable, XML, SQL, Command chains, GPars, Scriptom, などなど
特に「DSL」Groovy1.8から、DSLがより書きやすくなった(特定条件下で)メソッド呼出の括弧が省略できる
たとえば
invite “You” to javaone
たとえば
invite(“You”).to(javaone)
コード一式
def invite(subject) { [ to : { target -> target.add(subject) } ]}def javaone = []
assert javaone == ["Nakano”, "<Your Name>"]
invite(“You”).to(javaone)
まずはinviteメソッドの呼出
def invite(subject) { [ to : { target -> target.add(subject) } ]}def javaone = []
assert javaone == ["Nakano”, "<Your Name>"]
invite(“You”).to(javaone)
クロージャを含むMapを返して
def invite(subject) { [ to : { target -> target.add(subject) } ]}def javaone = []
assert javaone == ["Nakano”, "<Your Name>"]
invite(“You”).to(javaone)
キーが“to”、値がクロージャの1エントリだけを持つMapがreturnされる
そのクロージャを呼出す!
def invite(subject) { [ to : { target -> target.add(subject) } ]}def javaone = []
assert javaone == ["Nakano”, "<Your Name>"]
invite(“You”).to(javaone)
このクロージャの呼出になる
結局こういうこと
def invite(subject) { [ to : { target -> target.add(subject) } ]}def javaone = []
assert javaone == ["Nakano”, "<Your Name>"]
invite(“You”).to(javaone)
結局はこれ↓が実行されたのと同じ
javaone.add(“You”)
DSLのための仕込みを裏に隠してしまえば
invite “You” to javaone
コードはとてもすっきりして、意味も一目瞭然
#4 内視鏡手術Keyhole Surgery
http://www.flickr.com/photos/larsjuh
内視鏡手術 (Keyhole Surgery)
Groovyスクリプトを接続できる小さなバックドアをシステムに設けておくアプリケーション全体を停止したりリコンパイルすることなく、Groovyスクリプトから直接的に不具合の分析や振る舞いの変更などを実施できる運用中における診断や保守、バグやセキュリティ上の緊急対応などで便利!
例)JenkinsのCLIセキュリティの確保には十分注意すること!
#5 無制限の解放 Unlimited Openness
http://www.flickr.com/photos/eiriknewth
無制限の開放 (Unlimited Openness)
最大限の生産性や柔軟性を得るため、アプリケーション全体をGroovyやGrailsで構築する将来の要求に備えてあらかじめ設計するなんて無理全てのコードが変化を受け入れられるようにPerlやPHP・Python・Rubyに続こう
十分な知識と経験を持つ小規模なチームで比較的シンプルなシステムを開発する場合は効果が高い複雑度が高いシステム・大規模なチーム・動的言語に不慣れな場合などには、逆効果になる場合も
#6 ゴーストライターGhost Writer
New!!
http://www.flickr.com/photos/striatic
ゴーストライター (Ghost Writer)
アノテーションをマーカーとした、AST変換によるコード生成を利用するコードを書いてないのに、バイトコードレベルで機能が盛り込まれる
AST変換の例@Immutable, @Log, @Delegate, @Lazy, @Singleton, @Bindable, @AutoClone, @TimedInterrupt, ...
@Log
@groovy.util.logging.Logclass Foo { def method() { log.info('info message') log.fine('fine message') log.severe('severe message') }}new Foo().method()
$ groovy astLog.groovy Nov 9, 2011 1:09:10 PM java_util_logging_Logger$info callINFO: info messageNov 9, 2011 1:09:10 PM java_util_logging_Logger$severe callSEVERE: severe message
@Immutable
@Immutableclass Foo { int x Date date = new Date(1000)}def a = new Foo(x:1)assert a.x == 1assert a.date.getTime() == 1000
a.date.setTime(2000)assert a.date.getTime() == 1000
a.x = 3
防御的コピーされるため、オブジェクトの状態を変更しても、元のオブジェクトに影響はない
フィールドに再代入しようとするとReadOnlyPropertyExceptionが発生する
@Singleton
@Singletonclass Foo { def hello() { "hello" }}
assert Foo.instance.hello() == "hello"
// => Caught: java.lang.RuntimeException:// Can't instantiate singleton Foo. Use Foo.instancenew Foo()
getInstance()を通して取得する
自分でnewしようとするとRuntimeExceptionが発生する
@Delegate
class StringList { @Delegate List<String> list = new ArrayList<String>()}
def stringList = new StringList()
stringList.add("A")stringList.add("B")
assert stringList == ["A", "B"]stringList.each { print it }// => AB
addメソッドは定義していないが、フィールドのlistに委譲されている
オリジナルのAST変換もつくれる
@HelloWorldx
$ groovy sample.groovyHello, World!
アノテーションのアンカーポイントとしてのダミー変数宣言
オリジナルのAST変換もつくれる@GroovyASTTransformationClass("org.jggug.kobo.gastah.HelloWorldASTTransformation")@Retention(RetentionPolicy.RUNTIME)public @interface HelloWorld { String value()}
@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)class HelloWorldASTTransformation extends ClassCodeVisitorSupport implements ASTTransformation {
SourceUnit sourceUnit // forced to override by super class
public void visit(ASTNode[] nodes, SourceUnit source) { AnnotatedNode target = (AnnotatedNode) nodes[1] AnnotationNode includeAnnotation = (AnnotationNode) nodes[0]
def additionNode = new AstBuilder().buildFromCode({ println "Hello, World!" })[0] def statements = additionNode.statements
// ブロック内の完全リプレース source.getAST().getStatementBlock().getStatements().clear() source.getAST().getStatementBlock().getStatements().addAll(0, statements) }}
https://github.com/nobeans/jggug-20110617
@HelloWorldぐらいならこのぐらいのコード量でOK
#7 小人さんスクリプトHouse-Elf
小人さんスクリプト(House-Elf)
プロジェクトで利用する種々のユーティリティツールをGroovyスクリプトとして書くビルド自動化、CI、デプロイ、インストーラ、サービス監視、通知、統計、ドキュメント生成、機能テスト、HTMLスクレイピング、テスト用データ生成、データ移行ツールなどなど
Groovyの便利さが手っ取り早く実感でき、プロジェクト内のGroovyへの理解や親しみも深まるはじめてGroovy導入を試してみるときにおすすめ
≪時間があれば≫本年惜しくもレギュラー圏外に漏れた2パターンも簡単に紹介します
プロトタイプ Prototype
Old!
http://www.flickr.com/photos/solarbotics
プロトタイプ (Prototype)
新技術やアルゴリズム、ユーザインタフェースなどの実現可能性検証のためのプロトタイプ開発にGroovy(やGrails、Griffon)を用いる開発したプロトタイプは、要件に応じて必要なら一部または全部をJavaで書き換え、そのまま製品・納入システムに発展させたり
スマート設定Smart Configuration
Old!
スマート設定 (Smart Configuration)
システムの設定ファイルとして、XMLやプロパティファイルではなくGroovyスクリプトを用いるGroovyの簡潔で読みやすい記法を活かした柔軟な設定表現ができる繰り返しや条件分岐なども自然に記述できる
Groovyの全機能が使えるので、環境に動的に適応する「スマートな(賢い)」設定を記述したり、設定記述用の専用DSLを導入することもできる
Groovyが、下克上を狙うNext Big JVM Langではなく、あくまでJavaに寄り添う健気な存在であることがうまくお伝えできたでしょうか?
参考資料
JavaOne2011の発表資料https://oracleus.wingateweb.com/published/oracleus2011/sessions/21080/S21080_1606050.pdf
プログラミングGroovy(技術評論社)http://gihyo.jp/book/2011/978-4-7741-4727-7