More Related Content Similar to Easy Going Groovy(Groovyを気軽に使いこなそう) Similar to Easy Going Groovy(Groovyを気軽に使いこなそう) (20) More from Uehara Junji (20) Easy Going Groovy(Groovyを気軽に使いこなそう)1. Groovyを気軽に
つかいこなそう
JJUG CCC 2010 BOF C-2
NTTソフトウェア株式会社
上原 潤二
2010.10.18
2010年10月19日火曜日
2. はじめに
Slide # 2 JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
3. 自己紹介
上原潤二
NTTソフトウェア株式会社
JGGUG運営委員
ブログ Grな日々 http://d.hatena.ne.jp/uehaj/
Grails徹底入門 2章執筆
JavaWorld記事執筆
3
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
4. 本日の内容
Groovyはやわかり
Groovyを使うとこんなに便利
GroovyServ
Groovy 1.8の新機能
4
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
6. Groovy
JVM上で動作するスクリプト言語
簡潔・高機能
記述量Java比1/2∼1/5
Javaとの高い相互運用性
Groovy Class=Java Class
Groovy Object=Java Object
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
7. コード例: Java
import java.io.*; BufferedReader bis = new BufferedReader
import java.net.*; (new InputStreamReader(ins));
String line;
public class SocketAccess { while ((line = bis.readLine()) != null) {
System.out.println(line);
public static void main(String[] args) { }
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
()); }
}
7
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
8. コード例: Groovy!
import java.io.*; BufferedReader bis = new BufferedReader
import java.net.*; (new InputStreamReader(ins));
String line;
public class SocketAccess { while ((line = bis.readLine()) != null) {
System.out.println(line);
public static void main(String[] args) { }
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
()); }
}
8
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
9. コード例: Groovy!
import java.io.*; BufferedReader bis = new BufferedReader
import java.net.*; (new InputStreamReader(ins));
String line;
public class SocketAccess { while ((line = bis.readLine()) != null) {
System.out.println(line);
public static void main(String[] args) { }
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
()); }
ポイント: 正しいJavaコードは一般に正
}
しいGroovyコードでもある(例外もある)
8
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
10. コード例: Groovy!
import java.io.*; BufferedReader bis = new BufferedReader
import java.net.*; (new InputStreamReader(ins));
String line;
public class SocketAccess { while ((line = bis.readLine()) != null) {
System.out.println(line);
public static void main(String[] args) { }
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
()); }
}
9
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
11. コード例: Groovy!
import java.io.*; BufferedReader bis = new BufferedReader
import java.net.*; (new InputStreamReader(ins));
String line;
public class SocketAccess { while ((line = bis.readLine()) != null) {
System.out.println(line);
public static void main(String[] args) { }
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
ポイント: java.io.*, java.net.*などは
()); }
暗黙にimport済み
}
9
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
12. コード例: Groovy!
BufferedReader bis = new BufferedReader
(new InputStreamReader(ins));
String line;
public class SocketAccess { while ((line = bis.readLine()) != null) {
System.out.println(line);
public static void main(String[] args) { }
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
()); }
}
10
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
13. コード例: Groovy!
BufferedReader bis = new BufferedReader
(new InputStreamReader(ins));
String line;
public class SocketAccess { while ((line = bis.readLine()) != null) {
System.out.println(line);
public static void main(String[] args) { }
Socket soc = null; }
InputStream ins = null; ポイント: クラス定義、mainメソッドは
catch (IOException e) {
OutputStream outs = null; 省略可 e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
()); }
}
10
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
14. コード例: Groovy!
BufferedReader bis = new BufferedReader
(new InputStreamReader(ins));
String line;
while ((line = bis.readLine()) != null) {
System.out.println(line);
}
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
());
11
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
15. コード例: Groovy!
BufferedReader bis = new BufferedReader
ポイント: チェック例外 (new InputStreamReader(ins));
も非チェック扱い String line;
while ((line = bis.readLine()) != null) {
System.out.println(line);
}
Socket soc = null; }
InputStream ins = null; catch (IOException e) {
OutputStream outs = null; e.printStackTrace();
try { try {
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream(); }
outs = soc.getOutputStream(); catch(IOException ex) {}
outs.write("GET / HTTP/1.0nn".getBytes }
());
11
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
16. コード例: Groovy!
BufferedReader bis = new BufferedReader
(new InputStreamReader(ins));
String line;
while ((line = bis.readLine()) != null) {
System.out.println(line);
}
Socket soc = null;
InputStream ins = null;
OutputStream outs = null;
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream();
outs = soc.getOutputStream();
outs.write("GET / HTTP/1.0nn".getBytes
());
12
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
17. コード例: Groovy!
BufferedReader bis = new BufferedReader
ポイント: 変数の型宣言 (new InputStreamReader(ins));
は省略可能 String line;
while ((line = bis.readLine()) != null) {
System.out.println(line);
}
Socket soc = null;
InputStream ins = null;
OutputStream outs = null;
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream();
outs = soc.getOutputStream();
outs.write("GET / HTTP/1.0nn".getBytes
());
12
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
18. コード例: Groovy!
bis = new BufferedReader(new
InputStreamReader(ins));
def line = null;
while ((line = bis.readLine()) != null) {
System.out.println(line);
}
def soc = null;
def ins = null;
def outs = null;
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream();
outs = soc.getOutputStream();
outs.write("GET / HTTP/1.0nn".getBytes
());
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
19. コード例: Groovy!
bis = new BufferedReader(new
ポイント: 読み込みスト InputStreamReader(ins));
リームの自動クローズなど def line = null;
while ((line = bis.readLine()) != null) {
System.out.println(line);
}
def soc = null;
def ins = null;
def outs = null;
soc = new Socket("www.java-users.jp", 80); if (soc != null) soc.close();
ins = soc.getInputStream();
outs = soc.getOutputStream();
outs.write("GET / HTTP/1.0nn".getBytes
());
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
20. コード例: Groovy!
bis = new BufferedReader(new
InputStreamReader(ins));
def line = null;
while ((line = bis.readLine()) != null) {
System.out.println(line);
}
}
new Socket("www.java-users.jp",
80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".getBytes
());
14
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
21. コード例: Groovy!
bis = new BufferedReader(new
ポイント: 行読み込みス InputStreamReader(ins));
トリームに対する行単位 def line = null;
の処理と、自動クローズ while ((line = bis.readLine()) != null) {
System.out.println(line);
}
}
new Socket("www.java-users.jp",
80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".getBytes
());
14
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
22. コード例: Groovy!
ins.eachLine{ line ->
System.out.println(line);
}
}
new Socket("www.java-users.jp",
80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".getBytes
());
15
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
23. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".getBytes());
ins.eachLine { line ->
System.out.println(line);
}
}
16
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
24. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".getBytes());
ins.eachLine { line ->
System.out.println(line);
}
}
17
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
25. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".getBytes());
ins.eachLine { line ->
System.out.println(line);
}
} ポイント: プロパティア
クセス記法でgetterを呼
び出せる
17
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
26. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes);
ins.eachLine { line ->
System.out.println(line);
}
}
18
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
27. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes);
ins.eachLine { line ->
System.out.println(line);
}
} ポイント: System.out.println,
Ssytem.out.printなどは
println,printと書ける
18
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
28. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes);
ins.eachLine { line ->
println(line);
}
}
19
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
29. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes);
ins.eachLine { line ->
println(line);
}
} ポイント: クロージャの引数
が1つなら、暗黙のクロー
ジャ引数itで参照できる。
19
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
30. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes);
ins.eachLine {
println(it);
}
}
20
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
31. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes);
ins.eachLine {
println(it);
}
} ポイント: 行末のセミコロ
ンは多くの場合省略可
20
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
32. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes)
ins.eachLine {
println(it)
}
}
21
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
33. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write("GET / HTTP/1.0nn".bytes)
ins.eachLine {
println(it)
}
} ポイント: 式文のトップレ
ベルがメソッド呼び出しな
ら引数の括弧は省略可能
21
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
34. コード例: Groovy!
new Socket("www.java-users.jp", 80).withStreams { ins, outs ->
outs.write "GET / HTTP/1.0nn".bytes
ins.eachLine {
println it
}
}
22
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
35. HTTPに限れば
println new URL("http://www.java-users.jp").text
23
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
36. HTTPに限れば
println new URL("http://www.java-users.jp").text
JavaからGroovyに書き直すと、大抵数
分の1程度にはなる。
マップリテラル、リストリテラルなどもコードが短
くなる要因として良く示されるが、Java 7で採用さ
れるので割愛。
23
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
37. Groovy Eco System
フレームワーク
付属ライブラリ群
Gaelyk
Grails(Web)
GSQL GSP,GORM
SwingBuilder Griffon(GUI)
MarkupBuilder
既存ツールへの組み込み
Groovy GMaven,Maven3
設定ファイル記述/DSL
Hudson JBoss
Gant FreeMind
先進的な取り組み
Gradle
Spock,EasyB Gpars
Groovy++
24
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
39. ケース1
やりたいこと
指定ファイルをbzip2圧縮して
httpファイルアップロード
開発時に使用するツールとして
メンバーの大半はJava開発者なので
Javaで書きたい
26
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
40. でも…
Javaだと作成したプログラムをメン
バーに配布するのが面倒!
コンパイルして
実行可能Jarに?
依存Jar群(commonsのjarとか)をダ
ウンロードしてもらって
いやいっそ、Mavenで
pom書いて
いっそ、RubyやPerlで… orz
27
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
41. そんな時こそGroovyですよ!
@Grab('net.sourceforge.htmlunit:htmlunit:2.8')
import com.gargoylesoftware.htmlunit.WebClient;
// AntのBzip2タスクを使って圧縮
new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")
// HtmlUnitを使ってファイルアップロード
url = "http://pukiwiki.example.com/index.php?
plugin=attach&pcmd=upload&page=test"
page = new WebClient().getPage(url)
file = page.getElementById('_p_attach_file')
file.valueAttribute = args[0]+".bz2"
page.getByXPath("//input[@value='アップロード']")[0].click()
28
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
42. そんな時こそGroovyですよ!
@Grab('net.sourceforge.htmlunit:htmlunit:2.8')
import com.gargoylesoftware.htmlunit.WebClient;
// AntのBzip2タスクを使って圧縮
new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")
// HtmlUnitを使ってファイルアップロード
url = "http://pukiwiki.example.com/index.php?
plugin=attach&pcmd=upload&page=test"
page = new WebClient().getPage(url)
file = page.getElementById('_p_attach_file')
file.valueAttribute = args[0]+".bz2"
page.getByXPath("//input[@value='アップロード']")[0].click()
Java資産の有
効活用
(HtmlUnit, Ant)
28
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
43. そんな時こそGroovyですよ!
@Grab('net.sourceforge.htmlunit:htmlunit:2.8')
import com.gargoylesoftware.htmlunit.WebClient;
// AntのBzip2タスクを使って圧縮
new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")
// HtmlUnitを使ってファイルアップロード
url = "http://pukiwiki.example.com/index.php?
plugin=attach&pcmd=upload&page=test"
page = new WebClient().getPage(url)
file = page.getElementById('_p_attach_file')
file.valueAttribute = args[0]+".bz2"
page.getByXPath("//input[@value='アップロード']")[0].click()
Java資産の有 依存ライブ
効活用 ラリの実行時
(HtmlUnit, Ant)
28 自動取得
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
44. そんな時こそGroovyですよ!
@Grab('net.sourceforge.htmlunit:htmlunit:2.8')
import com.gargoylesoftware.htmlunit.WebClient;
// AntのBzip2タスクを使って圧縮
new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")
// HtmlUnitを使ってファイルアップロード
url = "http://pukiwiki.example.com/index.php?
plugin=attach&pcmd=upload&page=test"
page = new WebClient().getPage(url)
file = page.getElementById('_p_attach_file')
file.valueAttribute = args[0]+".bz2"
page.getByXPath("//input[@value='アップロード']")[0].click()
Java資産の有 依存ライブ コンパイル
効活用 ラリの実行時 不要
(HtmlUnit, Ant)
28 自動取得
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
45. もうちょっと詳しくー1
@Grab('net.sourceforge.htmlunit:htmlunit:2.8')
import com.gargoylesoftware.htmlunit.WebClient;
group指定 module指定 versoin指定
Grape
Groovyスクリプト用の依存
Jarのダウンロード・管理機構
Apache Ivyベース
Mavenリポジトリも扱える
29
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
46. もうちょっと詳しく-2
// AntのBzip2タスクを使って圧縮
new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")
argsはコマンドライン引数を表す
暗黙引数
Antは組み込まれている
他に、JUnit, commons-logging,
commons-cli, jlineなどがGroovy
配布パッケージに同梱
30
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
47. ケース2
やりたいこと
指定したCSVファイルの内容を
処理してDBテーブルに投入
DBにクエリをかける
開発システムに含まれるJavaコードで処
理した結果を投入する必要があるとする
31
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
48. ケース2
やりたいこと
指定したCSVファイルの内容を
処理してDBテーブルに投入
DBにクエリをかける
東京,35676000,日本
ニューヨーク,19040000,アメリカ合衆国
ブリッジポート=スタンフォード,1018000,アメリカ合衆国
フィラデルフィア,5492000,アメリカ合衆国
開発システムに含まれるJavaコードで処
理した結果を投入する必要があるとする
31
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
49. ケース2
やりたいこと
指定したCSVファイルの内容を
処理してDBテーブルに投入
DBにクエリをかける
東京,35676000,日本
ニューヨーク,19040000,アメリカ合衆国
都市名, 人口, 国名 ブリッジポート=スタンフォード,1018000,アメリカ合衆国
フィラデルフィア,5492000,アメリカ合衆国
開発システムに含まれるJavaコードで処
理した結果を投入する必要があるとする
31
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
50. そんな時にはGroovyですよ!
@Grab('com.h2database:h2:1.2.143')
@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
sql = Sql.newInstance("jdbc:h2:cities")
sql.execute """ CREATE TABLE Cities (
id INT IDENTITY PRIMARY KEY, name VARCHAR,
population DECIMAL(10), country VARCHAR)"""
cities = sql.dataSet("Cities")
new File("cities.csv").splitEachLine(",") { f1, f2, f3 ->
// 何らかの処理
cities.add(name:f1, population:f2, country:f3)
}
assert cities.findAll{ it.country=="日本" &&
it.population>1000000 }.rows()*.name ==
['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']
32
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
51. そんな時にはGroovyですよ!
@Grab('com.h2database:h2:1.2.143')
@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
sql = Sql.newInstance("jdbc:h2:cities")
sql.execute """ CREATE TABLE Cities (
id INT IDENTITY PRIMARY KEY, name VARCHAR,
population DECIMAL(10), country VARCHAR)"""
cities = sql.dataSet("Cities")
new File("cities.csv").splitEachLine(",") { f1, f2, f3 ->
// 何らかの処理
cities.add(name:f1, population:f2, country:f3)
}
assert cities.findAll{ it.country=="日本" &&
it.population>1000000 }.rows()*.name ==
['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']
H2 DBも自
動でダウン
32
Slide #ロード JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
52. そんな時にはGroovyですよ!
@Grab('com.h2database:h2:1.2.143')
@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
sql = Sql.newInstance("jdbc:h2:cities")
sql.execute """ CREATE TABLE Cities (
id INT IDENTITY PRIMARY KEY, name VARCHAR,
population DECIMAL(10), country VARCHAR)"""
cities = sql.dataSet("Cities")
new File("cities.csv").splitEachLine(",") { f1, f2, f3 ->
// 何らかの処理
cities.add(name:f1, population:f2, country:f3)
}
assert cities.findAll{ it.country=="日本" &&
it.population>1000000 }.rows()*.name ==
['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']
H2 DBも自 where句の
動でダウン 自動生成
32
Slide #ロード JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
53. そんな時にはGroovyですよ!
@Grab('com.h2database:h2:1.2.143')
@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
sql = Sql.newInstance("jdbc:h2:cities")
sql.execute """ CREATE TABLE Cities (
id INT IDENTITY PRIMARY KEY, name VARCHAR,
population DECIMAL(10), country VARCHAR)"""
cities = sql.dataSet("Cities")
new File("cities.csv").splitEachLine(",") { f1, f2, f3 ->
// 何らかの処理
cities.add(name:f1, population:f2, country:f3)
}
assert cities.findAll{ it.country=="日本" &&
it.population>1000000 }.rows()*.name ==
['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']
H2 DBも自 where句の insertも簡
動でダウン 自動生成 単
32
Slide #ロード JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
54. そんな時にはGroovyですよ!
@Grab('com.h2database:h2:1.2.143') Javaコード
@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
は自由に呼
sql = Sql.newInstance("jdbc:h2:cities") べる
sql.execute """ CREATE TABLE Cities (
id INT IDENTITY PRIMARY KEY, name VARCHAR,
population DECIMAL(10), country VARCHAR)"""
cities = sql.dataSet("Cities")
new File("cities.csv").splitEachLine(",") { f1, f2, f3 ->
// 何らかの処理
cities.add(name:f1, population:f2, country:f3)
}
assert cities.findAll{ it.country=="日本" &&
it.population>1000000 }.rows()*.name ==
['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']
H2 DBも自 where句の insertも簡
動でダウン 自動生成 単
32
Slide #ロード JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
55. もうちょっと詳しく-3
@Grab('com.h2database:h2:1.2.143')
@GrabConfig(systemClassLoader=true)
import groovy.sql.Sql
Grabは、実行ダウンロード&クラスパ
スへの追加
デフォルトだとGroovyClassLoaderで
読み込まれる
Class.forName()で読み込めるように、
システムクラスローダーを指定
jdbcの初期化で必要
33
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
56. もうちょっと詳しく-4
cities = sql.dataSet("Cities")
new File("cities.csv").splitEachLine(",") { f1, f2, f3 ->
// 何らかの処理
cities.add(name:f1, population:f2, country:f3)
}
DataSetは簡易なSQLインターフェー
ス
splitEachLineはGDKメソッド
addでinsert
フィールド名はMapのキーで指定
34
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
57. もうちょっと詳しく-5
cities = sql.dataSet("Cities")
:
assert cities.findAll{ it.country=="日本" &&
it.population>1000000 }.rows()*.name ==
['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']
上は以下と同じ
cities = sql.dataSet("Cities")
:
assert cities.findAll{ it.country=="日本" }
.findAll{ it.population>1000000 }.rows()*.name ==
['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']
findAllの式は遅延評価されて最後にSelect
が1回実行。
35
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
58. 他の例…g100pon(1)
実用スクリプト例の集成
Groovyスクリプト100本切り
JGGUG合宿2010の企画
実用スクリプト群100本をよって
たかって作っちゃえ!
本成果は、11/09 JGGUG主催G*
ワークショップにて報告予定(後述)
http://kokucheese.com/event/index/5267/
36
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
59. g100pon(2)
http://kokucheese.com/event/index/5267/
37
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
62. MacOSX / Linux
port install groovy
apt-get install groovy
やや古い(かも)
40
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
63. GroovyServ
http://kobo.github.com/groovyserv/
Slide # 41 JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
64. GroovyServって何?
Groovyスクリプト起動が爆速に!
(x10∼20)
Groovy処理系を常駐起動(groovyserver)
Groovyスクリプト実行は、処理を
groovyserverに移譲する小さなCプログ
ラムで行う(groovyclient)
server∼client間はsocket通信
Apache 2 Licenseでソース公開
MacOS X/Linux/Windows用バイナリ有
42
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
65. 構成図
Shell Environment User Groovy
Srcipt
C
LA
SS . lin
PA
cm
System.in
TH
d
System.out
en
e
v
SYstem.err
ar
gs
Ctrl-C
groovyclient TCP/IP
groovyserver
n
di
st
de t
st dou
rr
JavaVM
st
exit status
File System
Authentication
Cookie File
Slide # JJUG CCC 2010 Fall / 2010.10.18
43
2010年10月19日火曜日
66. 通常のGroovy実行
User Groovy
Shell Environment
Srcipt
C
LA
System.in
SS . lin
PA
cm
System.out
TH
d
SYstem.err
en
e
v
ar
gs
Ctrl-C
groovy
n
di
st
de t
st dou
JavaVM
rr
st
exit status
File System
44
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
67. 起動速度向上効果(Win)
19.6
倍
groovy -e println hello world
実行時間(sec) 比率
normal groovy 3.041 1.0
Installer版groovy 1.262 2.4
groovyclient(C版) 0.155 19.6
groovyclient(Ruby版) 0.193 15.8
•Groovy 1.7.3, GroovyServ 0.4-SNAPSHOT, WinXP SP3,Core2Duo 2GHz,JDK1
Slide # •timeコマンドでreal時間を計測。10回実行した平均。
JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日 45
68. 起動速度向上効果(Mac)
35.8
倍
groovy -e println hello world
実行時間(sec) 比率
normal groovy 1.112 1.0
Mac Ports版groovy(1.7.2) 0.321 3.5
groovyclient(C版) 0.031 35.8
groovyclient(Ruby版) 0.041 27.1
•Groovy 1.7.3, GroovyServ 0.4-SNAPSHOT, MacOSX 10.6.3, MacBook Core2duo 2.53GHz, JDK1.6.0u20
46
•timeコマンドでreal時間を計測。10回実行した平均。
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
69. 実行速度の向上効果(Win)
Server VM
の良いところ
取り利用
for (i=0; i<1000000; i++) {};
実行時間(msec)
groovy(Client VM) 593.7
groovy(Server VM) 243.8
groovyclient(Client VM) 454.6
groovyclient(Server VM) 197.0
47 •Groovy 1.7.3, GroovyServ 0.4, Windows XP SP3(cygwin 1.7.5),Core2duo 2.00GHz, JDK1.6.0u13
Slide # JJUG CCC 2010 Fall / 2010.10.18
•time コマンドで real 時間を計測。十回実行した平均。
2010年10月19日火曜日
70. 応用例: scalacの高速化
Groovy限
定ではない
for (i=0; i<1000000; i++) {};
実行時間(msec) scalacとの比率
scalac 6.6 1.0
fsc 1.2 5.5
scalac/GroovyServ 1.1 6.6
fsc/GroovyServ 0.4 16.5
48
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
71. Groovyスクリプト開発
Groovyは本来PerlやRubyにも対抗しうる機能を
持ったスクリプト言語
ワンライナー用オプション(-e, -p, -n, -i.bak, -l)
フィルタ、パイプ
コンパイル不要
でも、レスポンス悪いとやる気が出ない
トライ&エラーを繰り返すため
➡ そこで、GroovyServですよ
49
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
72. groovy-flymake
GroovyServと組合せてgroovycをバックグ
ラウンドで高速実行
http://gist.github.com/630992
50
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
73. 苦労しているところ
本当は1つのJVMを、スクリプトごとに占有し
ているように見せかける
並行実行は不可避(Groovyのフィルタスクリプトをpipeで繋いで実行)
異なるクラスローダで読み込ませる
stdin/stdout/strerrを多重化して1ソケットで相互転送
カレントディレクトリをJNA(Java Native Access)で変更
System.exit()をトラップしてexit statusをクライアントに転送
セキュリティ対策
秘密のクッキーファイルをserver-clientで共有し、ファイルシステム
のアクセス制御に基づいた保護
51
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
74. 効果が薄い用途
サーバ開発
GUIアプリケーション
CUIアプリでシェルのように起動して
操作するもの
cronで定期的に起動するもの
➡ 起動レスポンスが重要ではないもの
52
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
75. Groovy 1.8
Slide # 53 JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
76. GEP3 ..メソッド呼び出しの括弧省略
Groovy 1.7.x
m1(a1).m2(a2).m3(a3)
Groovy 1.8.xでは以下のよ
うに書ける
m1 a1 m2 a2 m3 a3
54
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
77. 日本語プログラミング言語Groovy(GEP3の応用例)
まず 100 の 平方根 を 表示する
そして 1 と 2 と 3 のうち、 奇数 それぞれに 対して { それ ->
二倍にした それ を 表示する
}
ついでに 1 から 100 のうち、 二の倍数.かつ(三の倍数) を 表示する
最後に 1 から 100 のうち、 二の倍数.かつ(三の倍数) それぞれに 対して
{ それ ->
とりあえず それ + "は6の倍数です" を 表示する
}
それはそれとして "以上" を 表示する
http://d.hatena.ne.jp/uehaj/20100919/1284906117
10.0 18は6の倍数です
2 24は6の倍数です
6
[6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, :
78, 84, 90, 96]
6は6の倍数です 96は6の倍数です
12は6の倍数です 以上
55
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
78. 日本語プログラミング言語Groovy(GEP3なしの時)
まず(100).の(平方根).を(表示する)
そして(1).と(2).と(3).のうち、(奇数).それぞれに(対して({それ ->
二倍にした(それ).を(表示する)
}))
ついでに(1).から(100).のうち、((二の倍数.かつ(三の倍数))).を(表示する)
最後に(1).から(100).のうち、(二の倍数.かつ(三の倍数)).それぞれに(対して
({ それ ->
とりあえず(それ + "は6の倍数です").を(表示する)
}))
それはそれとして("以上").を(表示する)
56
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
79. 拡張子によってAST変換起動
例) GrUnit…拡張子*.grunitはGrUnitのテストコードとし
て解釈
スクリプト用のユニットテスト記法
メソッド付属アノテーションの引数としてテストコードを書ける
@Typed
class Calculator {
testTestsExists {
private ArrayList<Double> list = []
assertTrue new File("./StdLibTest/
tests/").exists()
@GrUnit({
}
assertEquals(10d, calc.push(10d).list[-1])
})
testSuperclassName {
Calculator push(double v) {
assertEquals
list.push(v)
"groovy.util.GroovyTestCase",
this
this.class.superclass.name
}
}
http://groovy.dzone.com/articles/grunit-groovy-way-unit-testing def finder = new FileNameFinder ()
http://groovy.dzone.com/articles/grunit-inline-tests-groovy
57 String [] names = finder.getFileNames
Slide # ("./StdLibTest/tests/", "**/*.groovy")
JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
80. アノテーション引数にクロージャ指定
例)GContract…DbC(契約に
よる設計)をGroovyに導入
@Invariant({ elements != null }) elements = preElements
class Stack { }
private List elements def boolean is_empty() {
elements.isEmpty()
@Ensures({ is_empty() }) }
public Stack() {
elements = [] @Requires({ !is_empty() })
} def last_item() {
elements.last()
@Requires({ preElements?.size() > }
0 })
@Ensures({ !is_empty() }) def count() {
public Stack(List preElements) { elements.size()
58
http://github.com/andresteingress/gcontracts/wiki
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
81. 多数のAST変換追加
@Log,@ScriptField,@Packag
eScope,@Synchronized,@In
heritConstructors,@Indexed
Properties,@AutoClone,@Au
toExternalize,@Canonical,@
EqualsAndHashCode,@ToSt
ring,@TupleConstructor
59 http://canoo.com/blog/2010/09/20/log-groovys-
Slide # JJUG CCC 2010 Fall / 2010.10.18
new-and-extensible-logging-conveniences/http://
2010年10月19日火曜日 canoo.com/blog/2010/09/20/log-groovys-new-and-
82. @Logアノテーション
@Log … オーバーヘッドなしロガーのインジェ
クション(java.util.Logger)
@Log4j…〃(Log4j)
@Slf4j…〃(Slf4j)
@Commons…〃(Commons Logger)
import groovy.util.logging.Log
@Log
class MyClass {
def invoke() {
log.info('... an info message')
log.fine('... a fine message')
}
}
http://canoo.com/blog/2010/09/20/log-groovys-new-and-extensible-logging-conveniences/
60
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
83. まとめ
Javaプログラマにとって
Groovyは超便利
Groovは進化し続けている!
61
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
84. まとめ
Javaプログラマにとって
Groovyは超便利 ケースによっては「使ったほうが
良い」を越え「 使うべき」レベル
Groovは進化し続けている!
61
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
85. まとめ
Javaプログラマにとって
Groovyは超便利 ケースによっては「使ったほうが
良い」を越え「 使うべき」レベル
Groovは進化し続けている!
11/9のJGGUG G*ワークショップ@品川 受付
中!! http://kokucheese.com/event/index/5267/
「Model on Grails-DCIアーキテクチャへの道すじ-」by 和智右桂
(@digitalsoul0124)
「JGGUG合宿2010報告」by 合宿参加メンバ代表
「G*なJavaOneレポート」 by 中野靖治(NTTソフトウェア), 関谷和愛
(JGGUG)
61
Slide # JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日
86. Q&A
Slide # 62 JJUG CCC 2010 Fall / 2010.10.18
2010年10月19日火曜日