easy going groovy(groovyを気軽に使いこなそう)

86
JJUG CCC 2010 BOF C-2 NTTソフトウェア株式会社 上原 潤二 2010.10.18 20101019日火曜日

Upload: -

Post on 06-May-2015

2.923 views

Category:

Business


0 download

TRANSCRIPT

Page 1: Easy Going Groovy(Groovyを気軽に使いこなそう)

Groovyを気軽につかいこなそう

JJUG CCC 2010 BOF C-2

NTTソフトウェア株式会社上原 潤二2010.10.18

2010年10月19日火曜日

Page 2: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

はじめに

2

2010年10月19日火曜日

Page 3: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

自己紹介上原潤二NTTソフトウェア株式会社JGGUG運営委員ブログ“Grな日々”“Grails徹底入門”2章執筆JavaWorld記事執筆

3

http://d.hatena.ne.jp/uehaj/

2010年10月19日火曜日

Page 4: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

本日の内容GroovyはやわかりGroovyを使うとこんなに便利GroovyServGroovy 1.8の新機能

4

2010年10月19日火曜日

Page 5: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

Groovyはやわかり

5

2010年10月19日火曜日

Page 6: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

GroovyJVM上で動作するスクリプト言語簡潔・高機能

記述量Java比1/2~1/5Javaとの高い相互運用性

Groovy Class=Java ClassGroovy Object=Java Object

2010年10月19日火曜日

Page 7: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Javaimport java.io.*;import java.net.*;

public class SocketAccess {

public static void main(String[] args) { Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} } }}

7

2010年10月19日火曜日

Page 8: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!import java.io.*;import java.net.*;

public class SocketAccess {

public static void main(String[] args) { Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} } }}

8

2010年10月19日火曜日

Page 9: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!import java.io.*;import java.net.*;

public class SocketAccess {

public static void main(String[] args) { Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} } }}

8

ポイント: 正しいJavaコードは一般に正しいGroovyコードでもある(例外もある)

2010年10月19日火曜日

Page 10: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!import java.io.*;import java.net.*;

public class SocketAccess {

public static void main(String[] args) { Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} } }}

9

2010年10月19日火曜日

Page 11: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!import java.io.*;import java.net.*;

public class SocketAccess {

public static void main(String[] args) { Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} } }}

9

ポイント: java.io.*, java.net.*などは暗黙にimport済み

2010年10月19日火曜日

Page 12: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

public class SocketAccess {

public static void main(String[] args) { Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} } }}

10

2010年10月19日火曜日

Page 13: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

public class SocketAccess {

public static void main(String[] args) { Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} } }}

10

ポイント: クラス定義、mainメソッドは省略可

2010年10月19日火曜日

Page 14: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} }

11

2010年10月19日火曜日

Page 15: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

Socket soc = null; InputStream ins = null; OutputStream outs = null; try { soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); try { if (soc != null) soc.close(); } catch(IOException ex) {} }

11

ポイント: チェック例外も非チェック扱い

2010年10月19日火曜日

Page 16: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

Socket soc = null; InputStream ins = null; OutputStream outs = null; soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); }

if (soc != null) soc.close();

12

2010年10月19日火曜日

Page 17: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

Socket soc = null; InputStream ins = null; OutputStream outs = null; soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

BufferedReader bis = new BufferedReader(new InputStreamReader(ins)); String line; while ((line = bis.readLine()) != null) { System.out.println(line); }

if (soc != null) soc.close();

12

ポイント: 変数の型宣言は省略可能

2010年10月19日火曜日

Page 18: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

def soc = null; def ins = null; def outs = null; soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

bis = new BufferedReader(new InputStreamReader(ins)); def line = null; while ((line = bis.readLine()) != null) { System.out.println(line); }

if (soc != null) soc.close();

2010年10月19日火曜日

Page 19: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

def soc = null; def ins = null; def outs = null; soc = new Socket("www.java-users.jp", 80); ins = soc.getInputStream(); outs = soc.getOutputStream(); outs.write("GET / HTTP/1.0\n\n".getBytes());

bis = new BufferedReader(new InputStreamReader(ins)); def line = null; while ((line = bis.readLine()) != null) { System.out.println(line); }

if (soc != null) soc.close();

ポイント: 読み込みストリームの自動クローズなど

2010年10月19日火曜日

Page 20: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs ->

outs.write("GET / HTTP/1.0\n\n".getBytes());

bis = new BufferedReader(new InputStreamReader(ins)); def line = null; while ((line = bis.readLine()) != null) { System.out.println(line); } }

14

2010年10月19日火曜日

Page 21: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs ->

outs.write("GET / HTTP/1.0\n\n".getBytes());

bis = new BufferedReader(new InputStreamReader(ins)); def line = null; while ((line = bis.readLine()) != null) { System.out.println(line); } }

14

ポイント: 行読み込みストリームに対する行単位の処理と、自動クローズ

2010年10月19日火曜日

Page 22: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs ->

outs.write("GET / HTTP/1.0\n\n".getBytes());

ins.eachLine{ line -> System.out.println(line); } }

15

2010年10月19日火曜日

Page 23: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".getBytes()); ins.eachLine { line -> System.out.println(line); } }

16

2010年10月19日火曜日

Page 24: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".getBytes()); ins.eachLine { line -> System.out.println(line); } }

17

2010年10月19日火曜日

Page 25: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".getBytes()); ins.eachLine { line -> System.out.println(line); } }

17

ポイント: プロパティアクセス記法でgetterを呼び出せる

2010年10月19日火曜日

Page 26: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes); ins.eachLine { line -> System.out.println(line); } }

18

2010年10月19日火曜日

Page 27: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes); ins.eachLine { line -> System.out.println(line); } }

18

ポイント: System.out.println, Ssytem.out.printなどはprintln,printと書ける

2010年10月19日火曜日

Page 28: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes); ins.eachLine { line -> println(line); } }

19

2010年10月19日火曜日

Page 29: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes); ins.eachLine { line -> println(line); } }

19

ポイント: クロージャの引数が1つなら、暗黙のクロージャ引数itで参照できる。

2010年10月19日火曜日

Page 30: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes); ins.eachLine { println(it); } }

20

2010年10月19日火曜日

Page 31: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes); ins.eachLine { println(it); } }

20

ポイント: 行末のセミコロンは多くの場合省略可

2010年10月19日火曜日

Page 32: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes) ins.eachLine { println(it) } }

21

2010年10月19日火曜日

Page 33: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write("GET / HTTP/1.0\n\n".bytes) ins.eachLine { println(it) } }

21

ポイント: 式文のトップレベルがメソッド呼び出しなら引数の括弧は省略可能

2010年10月19日火曜日

Page 34: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

コード例: Groovy!

new Socket("www.java-users.jp", 80).withStreams { ins, outs -> outs.write "GET / HTTP/1.0\n\n".bytes ins.eachLine { println it } }

22

2010年10月19日火曜日

Page 35: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

HTTPに限ればprintln new URL("http://www.java-users.jp").text

23

2010年10月19日火曜日

Page 36: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

HTTPに限ればprintln new URL("http://www.java-users.jp").text

23

JavaからGroovyに書き直すと、大抵数分の1程度にはなる。

マップリテラル、リストリテラルなどもコードが短くなる要因として良く示されるが、Java 7で採用されるので割愛。

2010年10月19日火曜日

Page 37: Easy Going Groovy(Groovyを気軽に使いこなそう)

設定ファイル記述/DSL

GantGradleSpock,EasyB

先進的な取り組み

GparsGroovy++

Slide # JJUG CCC 2010 Fall / 2010.10.18

Groovy Eco System

既存ツールへの組み込み

GMaven,Maven3HudsonFreeMind

付属ライブラリ群

GSQLSwingBuilderMarkupBuilder

フレームワーク

Grails(Web)GSP,GORM

Griffon(GUI)

Groovy

Gaelyk

JBoss

24

2010年10月19日火曜日

Page 38: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

Groovyを使うとこんなに便利

25

2010年10月19日火曜日

Page 39: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

ケース1

開発時に使用するツールとしてメンバーの大半はJava開発者なのでJavaで書きたい

26

やりたいこと

指定ファイルをbzip2圧縮してhttpファイルアップロード

2010年10月19日火曜日

Page 40: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

でも…

27

Javaだと作成したプログラムをメンバーに配布するのが面倒!コンパイルして

実行可能Jarに?依存Jar群(commonsのjarとか)をダウンロードしてもらって

いやいっそ、Mavenでpom書いて

いっそ、RubyやPerlで… orz

2010年10月19日火曜日

Page 41: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時こそGroovyですよ!

28

@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()

2010年10月19日火曜日

Page 42: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時こそGroovyですよ!

28

@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)

2010年10月19日火曜日

Page 43: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時こそGroovyですよ!

28

@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)

2010年10月19日火曜日

Page 44: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時こそGroovyですよ!

28

@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)

2010年10月19日火曜日

Page 45: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

もうちょっと詳しくー1

29

@Grab('net.sourceforge.htmlunit:htmlunit:2.8')import com.gargoylesoftware.htmlunit.WebClient;

GrapeGroovyスクリプト用の依存Jarのダウンロード・管理機構Apache IvyベースMavenリポジトリも扱える

module指定group指定 versoin指定

2010年10月19日火曜日

Page 46: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

もうちょっと詳しく-2

30

// AntのBzip2タスクを使って圧縮new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")

argsはコマンドライン引数を表す暗黙引数Antは組み込まれている他に、JUnit, commons-logging, commons-cli, jlineなどがGroovy配布パッケージに同梱

2010年10月19日火曜日

Page 47: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

ケース2

開発システムに含まれるJavaコードで処理した結果を投入する必要があるとする31

やりたいこと

指定したCSVファイルの内容を処理してDBテーブルに投入DBにクエリをかける

2010年10月19日火曜日

Page 48: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

ケース2

開発システムに含まれるJavaコードで処理した結果を投入する必要があるとする31

やりたいこと

指定したCSVファイルの内容を処理してDBテーブルに投入DBにクエリをかける

東京,35676000,日本 ニューヨーク,19040000,アメリカ合衆国 ブリッジポート=スタンフォード,1018000,アメリカ合衆国 フィラデルフィア,5492000,アメリカ合衆国

2010年10月19日火曜日

Page 49: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

ケース2

開発システムに含まれるJavaコードで処理した結果を投入する必要があるとする31

やりたいこと

指定したCSVファイルの内容を処理してDBテーブルに投入DBにクエリをかける

東京,35676000,日本 ニューヨーク,19040000,アメリカ合衆国 ブリッジポート=スタンフォード,1018000,アメリカ合衆国 フィラデルフィア,5492000,アメリカ合衆国

都市名, 人口, 国名

2010年10月19日火曜日

Page 50: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時にはGroovyですよ!

32

@Grab('com.h2database:h2:1.2.143')@GrabConfig(systemClassLoader=true)import groovy.sql.Sqlsql = 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 == ['東京', '大阪=神戸 (阪神)', '京都', '名古屋', '福岡']

2010年10月19日火曜日

Page 51: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時にはGroovyですよ!

32

@Grab('com.h2database:h2:1.2.143')@GrabConfig(systemClassLoader=true)import groovy.sql.Sqlsql = 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も自動でダウンロード

2010年10月19日火曜日

Page 52: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時にはGroovyですよ!

32

@Grab('com.h2database:h2:1.2.143')@GrabConfig(systemClassLoader=true)import groovy.sql.Sqlsql = 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句の自動生成

2010年10月19日火曜日

Page 53: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時にはGroovyですよ!

32

@Grab('com.h2database:h2:1.2.143')@GrabConfig(systemClassLoader=true)import groovy.sql.Sqlsql = 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も簡単

2010年10月19日火曜日

Page 54: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

そんな時にはGroovyですよ!

32

@Grab('com.h2database:h2:1.2.143')@GrabConfig(systemClassLoader=true)import groovy.sql.Sqlsql = 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も簡単

Javaコードは自由に呼べる

2010年10月19日火曜日

Page 55: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

もうちょっと詳しく-3

33

@Grab('com.h2database:h2:1.2.143')@GrabConfig(systemClassLoader=true)import groovy.sql.Sql

Grabは、実行ダウンロード&クラスパスへの追加デフォルトだとGroovyClassLoaderで読み込まれるClass.forName()で読み込めるように、システムクラスローダーを指定

jdbcの初期化で必要

2010年10月19日火曜日

Page 56: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

もうちょっと詳しく-4

34

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のキーで指定

2010年10月19日火曜日

Page 57: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

もうちょっと詳しく-5

35

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回実行。

2010年10月19日火曜日

Page 58: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

他の例…g100pon(1)実用スクリプト例の集成Groovyスクリプト100本切りJGGUG合宿2010の企画実用スクリプト群100本をよってたかって作っちゃえ!本成果は、11/09 JGGUG主催G*ワークショップにて報告予定(後述)

36

http://kokucheese.com/event/index/5267/

2010年10月19日火曜日

Page 59: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

g100pon(2)

37

http://kokucheese.com/event/index/5267/

2010年10月19日火曜日

Page 60: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

インストールも簡単

38

2010年10月19日火曜日

Page 61: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

Windows Installer

39

2010年10月19日火曜日

Page 62: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

MacOSX / Linux

40

port install groovyapt-get install groovyやや古い(かも)

2010年10月19日火曜日

Page 63: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

GroovyServ

41

http://kobo.github.com/groovyserv/

2010年10月19日火曜日

Page 64: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

GroovyServって何?Groovyスクリプト起動が爆速に!(x10~20)Groovy処理系を常駐起動(groovyserver)Groovyスクリプト実行は、処理をgroovyserverに移譲する小さなCプログラムで行う(groovyclient)server~client間はsocket通信Apache 2 Licenseでソース公開MacOS X/Linux/Windows用バイナリ有

42

2010年10月19日火曜日

Page 65: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

構成図

JavaVM

Shell Environment

TCP/IPgroovyserver

groovyclientCtrl-C

stdin

stdou

tstd

err

exit status

CLASSPATH env

cmd. line args

File System

AuthenticationCookie File

User GroovySrcipt

System.in System.outSYstem.err

432010年10月19日火曜日

Page 66: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

通常のGroovy実行Shell Environment

JavaVM

groovyCtrl-C

stdin

stdou

t

CLASSPATH env

cmd. line args

File System

User GroovySrcipt

System.in System.outSYstem.err

stderr

exit status

44

2010年10月19日火曜日

Page 67: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

起動速度向上効果(Win)

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•timeコマンドでreal時間を計測。10回実行した平均。

19.6倍

452010年10月19日火曜日

Page 68: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

起動速度向上効果(Mac)

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•timeコマンドでreal時間を計測。10回実行した平均。

35.8倍

46

2010年10月19日火曜日

Page 69: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

実行速度の向上効果(Win)

実行時間(msec)groovy(Client VM) 593.7

groovy(Server VM) 243.8

groovyclient(Client VM) 454.6

groovyclient(Server VM) 197.0

for (i=0; i<1000000; i++) {};

•Groovy 1.7.3, GroovyServ 0.4, Windows XP SP3(cygwin 1.7.5),Core2duo 2.00GHz, JDK1.6.0u13•time コマンドで real 時間を計測。十回実行した平均。

Server VMの良いところ取り利用

47

2010年10月19日火曜日

Page 70: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

応用例: scalacの高速化

実行時間(msec) scalacとの比率scalac 6.6 1.0

fsc 1.2 5.5

scalac/GroovyServ 1.1 6.6

fsc/GroovyServ 0.4 16.5

for (i=0; i<1000000; i++) {};

Groovy限定ではない

48

2010年10月19日火曜日

Page 71: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

Groovyスクリプト開発Groovyは本来PerlやRubyにも対抗しうる機能を持ったスクリプト言語

ワンライナー用オプション(-e, -p, -n, -i.bak, -l)

フィルタ、パイプ

コンパイル不要

でも、レスポンス悪いとやる気が出ないトライ&エラーを繰り返すため

➡ そこで、GroovyServですよ

49

2010年10月19日火曜日

Page 72: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

groovy-flymake

50

GroovyServと組合せてgroovycをバックグラウンドで高速実行

http://gist.github.com/630992

2010年10月19日火曜日

Page 73: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

苦労しているところ本当は1つのJVMを、スクリプトごとに占有しているように見せかける並行実行は不可避(Groovyのフィルタスクリプトをpipeで繋いで実行)

異なるクラスローダで読み込ませる

stdin/stdout/strerrを多重化して1ソケットで相互転送

カレントディレクトリをJNA(Java Native Access)で変更

System.exit()をトラップしてexit statusをクライアントに転送

セキュリティ対策秘密のクッキーファイルをserver-clientで共有し、ファイルシステムのアクセス制御に基づいた保護

51

2010年10月19日火曜日

Page 74: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

効果が薄い用途サーバ開発GUIアプリケーションCUIアプリでシェルのように起動して操作するものcronで定期的に起動するもの

➡ 起動レスポンスが重要ではないもの

52

2010年10月19日火曜日

Page 75: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

Groovy 1.8

53

2010年10月19日火曜日

Page 76: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

GEP3 ..メソッド呼び出しの括弧省略

54

Groovy 1.7.xm1(a1).m2(a2).m3(a3)Groovy 1.8.xでは以下のように書けるm1 a1 m2 a2 m3 a3

2010年10月19日火曜日

Page 77: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

日本語プログラミング言語Groovy(GEP3の応用例)

まず 100 の 平方根 を 表示するそして 1 と 2 と 3 のうち、 奇数 それぞれに 対して { それ ->  二倍にした それ を 表示する}ついでに 1 から 100 のうち、 二の倍数.かつ(三の倍数) を 表示する

最後に 1 から 100 のうち、 二の倍数.かつ(三の倍数) それぞれに 対して { それ ->  とりあえず それ + "は6の倍数です" を 表示する}それはそれとして "以上" を 表示する

55

10.026[6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96]6は6の倍数です12は6の倍数です

18は6の倍数です24は6の倍数です: 96は6の倍数です以上

http://d.hatena.ne.jp/uehaj/20100919/1284906117

2010年10月19日火曜日

Page 78: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

日本語プログラミング言語Groovy(GEP3なしの時)

まず(100).の(平方根).を(表示する)そして(1).と(2).と(3).のうち、(奇数).それぞれに(対して({それ ->  二倍にした(それ).を(表示する)}))ついでに(1).から(100).のうち、((二の倍数.かつ(三の倍数))).を(表示する)

最後に(1).から(100).のうち、(二の倍数.かつ(三の倍数)).それぞれに(対して({ それ ->  とりあえず(それ + "は6の倍数です").を(表示する)}))それはそれとして("以上").を(表示する)

56

2010年10月19日火曜日

Page 79: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

拡張子によってAST変換起動例) GrUnit…拡張子*.grunitはGrUnitのテストコードとして解釈

スクリプト用のユニットテスト記法メソッド付属アノテーションの引数としてテストコードを書ける

57http://groovy.dzone.com/articles/grunit-inline-tests-groovy

@Typedclass Calculator { private ArrayList<Double> list = []

@GrUnit({ assertEquals(10d, calc.push(10d).list[-1]) }) Calculator push(double v) { list.push(v) this }

testTestsExists { assertTrue new File("./StdLibTest/tests/").exists()}

testSuperclassName { assertEquals "groovy.util.GroovyTestCase", this.class.superclass.name}

def finder = new FileNameFinder ()

String [] names = finder.getFileNames("./StdLibTest/tests/", "**/*.groovy")

http://groovy.dzone.com/articles/grunit-groovy-way-unit-testing

2010年10月19日火曜日

Page 80: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

アノテーション引数にクロージャ指定

例)GContract…DbC(契約による設計)をGroovyに導入

58http://github.com/andresteingress/gcontracts/wiki

@Invariant({ elements != null })class Stack {

private List elements

@Ensures({ is_empty() }) public Stack() { elements = [] }

@Requires({ preElements?.size() > 0 }) @Ensures({ !is_empty() }) public Stack(List preElements) {

elements = preElements }

def boolean is_empty() { elements.isEmpty() }

@Requires({ !is_empty() }) def last_item() { elements.last() }

def count() { elements.size()

2010年10月19日火曜日

Page 82: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

@Logアノテーション@Log … オーバーヘッドなしロガーのインジェクション(java.util.Logger)@Log4j…〃(Log4j)@Slf4j…〃(Slf4j)@Commons…〃(Commons Logger)

60http://canoo.com/blog/2010/09/20/log-groovys-new-and-extensible-logging-conveniences/

import groovy.util.logging.Log@Logclass MyClass { def invoke() { log.info('... an info message') log.fine('... a fine message') }}

2010年10月19日火曜日

Page 83: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

まとめ

61

JavaプログラマにとってGroovyは超便利Groovは進化し続けている!

2010年10月19日火曜日

Page 84: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

まとめ

61

JavaプログラマにとってGroovyは超便利Groovは進化し続けている!

ケースによっては「使ったほうが良い」を越え「 使うべき」レベル

2010年10月19日火曜日

Page 85: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

まとめ

61

JavaプログラマにとってGroovyは超便利Groovは進化し続けている!

ケースによっては「使ったほうが良い」を越え「 使うべき」レベル

11/9のJGGUG G*ワークショップ@品川 受付中!!「Model on Grails-DCIアーキテクチャへの道すじ-」by 和智右桂

(@digitalsoul0124)

「JGGUG合宿2010報告」by 合宿参加メンバ代表「G*なJavaOneレポート」 by 中野靖治(NTTソフトウェア), 関谷和愛

(JGGUG)

http://kokucheese.com/event/index/5267/

2010年10月19日火曜日

Page 86: Easy Going Groovy(Groovyを気軽に使いこなそう)

Slide # JJUG CCC 2010 Fall / 2010.10.18

Q&A

62

2010年10月19日火曜日