85
プログラミング G* JJUG CCC 2011 Spring @kiy0taka

JJUG CCC 2011 Spring

Embed Size (px)

Citation preview

Page 1: JJUG CCC 2011 Spring

プログラミング G*

JJUG CCC 2011 Spring@kiy0taka

Page 2: JJUG CCC 2011 Spring

自己紹介•奥清隆(おく きよたか)

• id:kiy0taka、@kiy0taka

•大阪在住

•日本Grails/Groovyユーザグループ

•関西Javaエンジニアの会

※ kiy0takaの0は数字のゼロ

Page 3: JJUG CCC 2011 Spring

G*とは

•じーあすたりすく、じーあすたー

• GroovyやGroovyに関する技術の総称

• Grails、Griffon、Gant、Gaelyk等

•詳しくは全国各地のJGGUG勉強会へ

Page 4: JJUG CCC 2011 Spring

Groovy?

Page 5: JJUG CCC 2011 Spring

HelloWorld.java

public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");

}}

Page 6: JJUG CCC 2011 Spring

HelloWorld.groovy

public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");

}}

Javaの構文とある程度互換性があるのでそのまま使える。

Page 7: JJUG CCC 2011 Spring

HelloWorld.groovy

public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!")

}}

セミコロンはなくても良い。

Page 8: JJUG CCC 2011 Spring

HelloWorld.groovy

public class HelloWorld {public static void main(String[] args) {System.out.println "Hello, World!"

}}

引数ありメソッド呼び出しの括弧は省略可能

Page 9: JJUG CCC 2011 Spring

HelloWorld.groovy

public static void main(String[] args) {System.out.println "Hello, World!"

}

クラスも省略可能

Page 10: JJUG CCC 2011 Spring

HelloWorld.groovy

System.out.println "Hello, World!"

mainメソッドも省略可能

Page 11: JJUG CCC 2011 Spring

HelloWorld.groovy

println "Hello, World!"

System.out.println → println

Page 12: JJUG CCC 2011 Spring

One-Liner

groovy -e "println 'Hello, World!'"

Page 13: JJUG CCC 2011 Spring

Java資産の超有効活用

Page 14: JJUG CCC 2011 Spring

Javaのクラスを普通に使える

def file = new File("./hoge.txt")

Page 15: JJUG CCC 2011 Spring

拡張されてる

def text = new File("./hoge.txt").text

Page 16: JJUG CCC 2011 Spring

Webページをとってくる

new URL('http://www.java-users.jp/contents/').getText('UTF-8')

Page 17: JJUG CCC 2011 Spring

Stringでコマンド実行

println 'ls -la /opt/local'.execute().text

total 8drwxr-xr-x 12 root admin 408 11 23 19:32 .drwxr-xr-x 3 root admin 102 11 7 14:34 ..drwxr-xr-x 5 root wheel 170 11 24 13:02 Librarydrwxr-xr-x 686 root admin 23324 11 27 18:06 bindrwxr-xr-x 25 root admin 850 11 24 17:01 etcdrwxr-xr-x 177 root admin 6018 11 24 17:01 includedrwxr-xr-x 988 root admin 33592 11 24 17:01 libdrwxr-xr-x 22 root admin 748 11 24 16:17 libexeclrwxr-xr-x 1 65534 wheel 9 11 23 18:42 man -> share/mandrwxr-xr-x 5 root admin 170 11 24 13:37 sbindrwxr-xr-x 76 root admin 2584 11 27 18:06 sharedrwxr-xr-x 8 root admin 272 11 24 13:02 var

Page 18: JJUG CCC 2011 Spring

よく使われるパッケージのimport文は書かなくて良い

import java.langimport java.mathimport java.ioimport java.netimport java.utilimport groovy.langimport groovy.util

Page 19: JJUG CCC 2011 Spring

Javaのライブラリもそのまま使える

import org.apache.poi.hssf.usermodel.*

def workBook = new HSSFWorkbook(new File('./foo.xls')workBook.newInputStream()).sheets.each { sheet -> sheet.firstRowNum.upto(sheet.lastRowNum) { sheet.getRow(it).with { row -> row.firstCellNum.upto(row.lastCellNum - 1) { println row.getCell(it).stringCellValue } } }}

Page 20: JJUG CCC 2011 Spring

jarファイルがなくてもいい

@Grab('org.apache.poi:poi:3.2-FINAL')import org.apache.poi.hssf.usermodel.*

def workBook = new HSSFWorkbook(new File('./foo.xls')workBook.newInputStream()).sheets.each { sheet -> sheet.firstRowNum.upto(sheet.lastRowNum) { sheet.getRow(it).with { row -> row.firstCellNum.upto(row.lastCellNum - 1) { println row.getCell(it).stringCellValue } } }}

Page 21: JJUG CCC 2011 Spring

Antが組み込まれているdef ant = new AntBuilder()

ant.unzip(src: 'xxx.zip', dest:'dest')

ant.mail(mailhost:'hostname', subject:'hello', charset:'utf-8', user:user, password:password) { from address:'[email protected]' to address:'[email protected]' message 'Hello World!'}

Page 22: JJUG CCC 2011 Spring

効率よくプログラミングする

ために

Page 23: JJUG CCC 2011 Spring

• Groovyの起動が速くなる

• JVM上で動く言語は起動に時間がかかる

•テンポよくスクリプトを実装できる

•日本人が開発

•@uehaj、@nobeans

Page 24: JJUG CCC 2011 Spring

// Groovy$ time groovy -e "println 'Hello'"Hello

real!0m1.292suser!0m1.283ssys!0m0.192s

// GroovyServ$ time groovyclient -e "println 'Hello'"Hello

real!0m0.036suser!0m0.001ssys!0m0.003s

Page 25: JJUG CCC 2011 Spring

ツールを作る

Page 26: JJUG CCC 2011 Spring

Swing(Java)package sample;

import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;

import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JTextArea;import javax.swing.SwingUtilities;

public class Hello extends JFrame {

public Hello() { super("Hello");

Container contentPane = getContentPane(); contentPane.setLayout(new GridLayout(3, 1));

JLabel label = new JLabel("Label"); contentPane.add(label);

JTextArea textArea = new JTextArea("Text Area"); textArea.setColumns(20); textArea.setRows(2); contentPane.add(textArea);

JButton button = new JButton("Button"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { ... } });

contentPane.add(button);

setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); setVisible(true); }

public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new Hello(); } }); }}

Page 27: JJUG CCC 2011 Spring

Groovy

import groovy.swing.SwingBuilder

new SwingBuilder().edt { frame(title:'Hello', show:true, pack:true) { gridLayout(cols:1, rows:3) label 'Label' textArea('Text Area', rows:2, columns:20) button('Button', actionPerformed:{ evt -> ... }) }}

Page 28: JJUG CCC 2011 Spring

import groovy.swing.SwingBuilder

new SwingBuilder().edt { frame(show:true, pack:true) { tableLayout { tr { td { label 'UserName: ' } td { textField columns:20 } } tr { td { label 'Password: ' } td { passwordField columns:20 } } tr { td(colspan:2) { button 'Login' } } } }}

SwingBuilder

Page 29: JJUG CCC 2011 Spring

https://gist.github.com/913279

Page 30: JJUG CCC 2011 Spring
Page 31: JJUG CCC 2011 Spring

h2console.groovy

@Grab('org.mortbay.jetty:jetty-embedded:6.1.25')@Grab('com.h2database:h2:1.2.144')@Grab('mysql:mysql-connector-java:5.1.13')import org.mortbay.jetty.Serverimport org.mortbay.jetty.servlet.Contextimport org.h2.server.web.WebServlet

def server = new Server(8080)new Context(server, "/", Context.SESSIONS).addServlet(WebServlet, "/*")

server.start()

https://gist.github.com/717932

Page 32: JJUG CCC 2011 Spring

Groovy 1.8 のチカラ

Page 33: JJUG CCC 2011 Spring

please show the square_root of 100

Page 34: JJUG CCC 2011 Spring

Command Chainshow = { println it }square_root = { Math.sqrt(it) }

def please(action) { [the: { what -> [of: { n -> action(what(n)) }] }]}

please(show).the(square_root).of(100)

Page 35: JJUG CCC 2011 Spring

show = { println it }square_root = { Math.sqrt(it) }

def please(action) { [the: { what -> [of: { n -> action(what(n)) }] }]}

please show the square_root of 100

Command Chain

Page 36: JJUG CCC 2011 Spring

Object.metaClass.を =

Object.metaClass.の =

{ clos -> clos(delegate) }

まず = { it }表示する = { println it }平方根 = { Math.sqrt(it) }

まず 100 の 平方根 を 表示する

Command Chain

Page 37: JJUG CCC 2011 Spring
Page 38: JJUG CCC 2011 Spring

GPars

• Groovy Parallel Systems

• Groovyで並列プログラミング

• GParsはGroovyのライブラリ

• Groovy 1.8からGroovyに組み込まれた

Page 39: JJUG CCC 2011 Spring

処理を並列化

import static groovyx.gpars.GParsPool.withPool

def list = [1, 2, 3, 4, 5]

withPool { def result = list.collectParallel { it * 2 } assert result == [2, 4, 6, 8, 10]}

Page 40: JJUG CCC 2011 Spring

JSONのサポート

Page 41: JJUG CCC 2011 Spring

JsonSlurperimport groovy.json.*

def text = '''[ ["aaa", "bbb", "ccc"], { "key1" : "value1", "key2" : "value2", "key3" : "value3", "key4" : "" }, ["ddd", "eee", "fff"]]'''

def slurper = new JsonSlurper()def json = slurper.parseText(text)

assert json == [ ["aaa", "bbb", "ccc"], [ "key1" : "value1", "key2" : "value2", "key3" : "value3", "key4" : "" ], ["ddd", "eee", "fff"]]

Page 42: JJUG CCC 2011 Spring

JsonBuilderimport groovy.json.*

def json = new JsonBuilder()json ( ["aaa", "bbb", "ccc"], [ "key1" : "value1", "key2" : "value2", "key3" : "value3", "key4" : "" ], ["ddd", "eee", "fff"])

println json

Page 43: JJUG CCC 2011 Spring

クロージャの拡張

Page 44: JJUG CCC 2011 Spring

アノテーションで利用import org.gcontracts.annotations.*

@Invariant({ speed() >= 0 })class Rocket {

@Requires({ isStarted() }) @Ensures({ old.speed < speed }) def accelerate() { ... }

boolean isStarted() { ... } def speed() { ... }

}

Page 45: JJUG CCC 2011 Spring

合成def plus2 = { it + 2 }def times3 = { it * 3 }

def times3plus2 = plus2 << times3assert times3plus2(3) == 11assert times3plus2(4) == plus2(times3(4))

def plus2times3 = times3 << plus2assert plus2times3(3) == 15assert plus2times3(5) == times3(plus2(5))

assert times3plus2(3) == (times3 >> plus2)(3)

Page 46: JJUG CCC 2011 Spring

その他• トランポリン

• 再帰処理をループに

• メモ化

• 同じ引数の結果を再利用

• カリー化

• 引数の右からカリー化

• 指定した位置の引数をカリー化

Page 47: JJUG CCC 2011 Spring

新しいAST変換

Page 48: JJUG CCC 2011 Spring

@Logimport groovy.util.logging.*

@Logclass Car { Car() { log.info 'Car constructed' }}

def c = new Car()

@Commons、@Log4j、@Slf4j

Page 49: JJUG CCC 2011 Spring

@Log、@Commons、@Log4j、@Slf4j、@Field、@PackageScope、

@AutoClone、@AutoExternalizable、@ThreadInterrupt、@TimedInterrupt、@ConditionalInterrupt、@ToString、

@EqualsAndHashCode、@TupleConstructor、@Canonical、@InheritConstructors、@WithReadLock、@WithWriteLock、

@ListenerList

Page 50: JJUG CCC 2011 Spring

Webアプリケーションを作る

Page 51: JJUG CCC 2011 Spring

Grails

•フルスタックなWebアプリケーションフレームワーク

• Java、Groovy、Spring、Hibernate、Sitemeshなど

•データベース(HSQLDB)、サーブレットコンテナ(Tomcat)がバンドルされていてすぐ使える!

Page 52: JJUG CCC 2011 Spring

コマンドによるサポート

create-appcreate-controllercreate-domain-classcreate-scriptcreate-servicecreate-tag-libcreate-unit-test

generate-allgenerate-controllergenerate-viewspackagerun-apprun-wartest-app

Page 53: JJUG CCC 2011 Spring

create-app

Page 54: JJUG CCC 2011 Spring

create-domain-classpackage myapp

class Message {

String text

static constraints = { text blank:false, maxSize:500 }}

Page 55: JJUG CCC 2011 Spring

create-controller

package myapp

class MessageController {

static scaffold = true}

Page 56: JJUG CCC 2011 Spring

run-app

Page 57: JJUG CCC 2011 Spring

generate-all

•静的スカッフォールディング

•コントローラ、ビューのコードを生成

•テンプレートを適用することも可能

Page 58: JJUG CCC 2011 Spring

GORM• Grails O/R Mapping

•Message.list(offset:10, max:10)

•Message.findAllByTextLike('...')

•Message.withCriteria { like('text', '...') }

• new Message(text:'...').save()

Page 59: JJUG CCC 2011 Spring

install-plugin• 600以上のプラグイン

•既存のJavaテクノロジをプラグインで取り込む

• Spring Security、Mail、App Engine

• Cassandra、MongoDB、Redis、Riak、GemfireなどのNoSQLにも対応

Page 60: JJUG CCC 2011 Spring

package

•WARファイルにパッケージ

• Java Webアプリケーションと同じ

• Tomcatなど、通常のサーブレットコンテナで動かせる

Page 61: JJUG CCC 2011 Spring

Google App Enginefor Groovy

Page 62: JJUG CCC 2011 Spring

• GAE/J用のGroovyツールキット

• GrailsもGAE/J対応してるが、ちょっとしたアプリをサクっと作れる

Page 63: JJUG CCC 2011 Spring

Gaelyk:Controller

log.info "Setting attribute datetime"

request.datetime = new Date().toString()

log.info "Forwarding to the template"

forward '/datetime.gtpl'

Page 64: JJUG CCC 2011 Spring

Gaelyk:View

<% include '/WEB-INF/includes/header.gtpl' %>

<h1>Date / time</h1>

<p> <% log.info "outputing the datetime attribute" %> The current date and time: ${request.datetime}</p>

<% include '/WEB-INF/includes/footer.gtpl' %>

Page 65: JJUG CCC 2011 Spring

Gaelyk:Datastore

import com.google.appengine.api.datastore.Entity

def entity = new Entity("person")entity.name = "Kiyotaka Oku"entity.age = 31

entity.save()

Page 66: JJUG CCC 2011 Spring

datastore blobstore

memcache oauth

urlFetch namespace

mail capabilities

images channel

users files

user backends

defaultQueue lifecycle

queues localMode

xmpp app

Page 67: JJUG CCC 2011 Spring

import com.google.appengine.api.datastore.*import static com.google.appengine.api.datastore.FetchOptions.Builder.*import static com.google.appengine.api.datastore.Query.FilterOperator.*import static com.google.appengine.api.datastore.Query.SortDirection.*

def query = new Query('person').with { addFilter 'age', GREATER_THAN_OR_EQUAL, 30 addSort 'name', ASCENDING}

def persons = datastore.prepare(query).asList(withLimit(21))

Gaelyk:Datastore

Page 68: JJUG CCC 2011 Spring

Gaelyk:Mail

mail.send sender: "[email protected]", to: "[email protected]", subject: "Hello", textBody: "Hello, how are you doing?"

Page 69: JJUG CCC 2011 Spring

Gaelyk:TaskQueue

defaultQueue << [ countdownMillis: 1000, url: "/task/dailyEmail", taskName: "Send daily email newsletter", method: 'PUT', params: [date: '20090914'], payload: content]

Page 70: JJUG CCC 2011 Spring

デスクトップアプリケーション

を作る

Page 71: JJUG CCC 2011 Spring

Griffon

•デスクトップアプリケーションフレームワーク

• Grailsを元に開発された

Page 72: JJUG CCC 2011 Spring

Getting Started

$ griffon create-app myapp$ cd myapp$ griffon run-app

Page 73: JJUG CCC 2011 Spring

GriffonのMVC

• Model -> POGO

• View -> SwingBuilder

• Controller -> Groovy

MVCをきちんと分けて実装できる

Page 74: JJUG CCC 2011 Spring

プラグイン

• 様々な機能をプラグインで提供

• CSS、JavaFX、Test、Look&Feel...

• 100以上のプラグインを利用可能

• プラグインのインストールもコマンド一発

• griffon install <プラグイン名>

Page 75: JJUG CCC 2011 Spring

パッケージング

• 「griffon package」

• Jar、Zip、Applet、Web Start で配布可能

• Installerプラグインでさらに色んな形式で

• .exe、.app、IzPack、RPM、DEB、DMG

Page 76: JJUG CCC 2011 Spring

ビルドする

Page 77: JJUG CCC 2011 Spring

Gradle•ビルドツール

•Mavenのように定型化したタスク

• Ivy、Mavenの依存関係の解決

• Antのように独自タスクも定義可能

•ビルドスクリプトはGroovyで記述

• XMLからの解放

Page 78: JJUG CCC 2011 Spring

build.gradle

apply plugin: 'groovy'

repositories { mavenCentral()}

dependencies { groovy 'org.codehaus.groovy:groovy:1.8.0' compile 'junit:junit:4.8.2'}

Page 79: JJUG CCC 2011 Spring

$ gradle clean build:clean:compileJava:compileGroovy:processResources:classes:jar:assemble:compileTestJava:compileTestGroovy:processTestResources:testClasses:test:check:build

BUILD SUCCESSFUL

Total time: 13.766 secs

Page 80: JJUG CCC 2011 Spring

独自タスクの定義task checksum << { fileList('../antLoadfileResources').each {File file -> ant.checksum(file: file, property: "cs_$file.name") println "$file.name Checksum: ${ant.properties["cs_$file.name"]}" }}

task loadfile << { fileList('../antLoadfileResources').each {File file -> ant.loadfile(srcFile: file, property: file.name) println "I'm fond of $file.name" }}

File[] fileList(String dir) { file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()}

Page 81: JJUG CCC 2011 Spring
Page 82: JJUG CCC 2011 Spring

もっと知りたい方は

•日本Grails/Groovyユーザーグループ

•首都圏では2ヶ月に1回のペースで勉強会

•名古屋、大阪でも

Page 83: JJUG CCC 2011 Spring

G*Magazine

• JGGUGが発行する定期(?)発行電子書籍

• PDFで配布中

• Vol. 0、Vol. 1公開中!

• Vol. 2は今週末(?)

• http://grails.jp/g_mag_jp/

Page 84: JJUG CCC 2011 Spring

勉強会予定• 5/28(土)

•レッツゴーデベロッパー 2011

• 6/17(金)

•G*ワークショップ

• 7/2(土)

• Groovyイン・アクション読書会

Page 85: JJUG CCC 2011 Spring

ご清聴、ありがとうございました。