Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

51
Grails-1.1を斬る! ~Grails-1.1からのチーム開発~ JGGUG 第弐回 g* workshop def speaker = new Cast(name:”T.Yamamoto”,version:”G*2-2009-05-08”) Grails-1.1.1リリース間近

description

第2回 g* ワークショップGrails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Transcript of Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Page 1: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grails-1.1を斬る!~Grails-1.1からのチーム開発~

JGGUG 第弐回 g* workshop

def speaker = new Cast(name:”T.Yamamoto”,version:”G*2-2009-05-08”)

Grails-1.1

.1リリース間

Page 2: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

自己紹介名前:山本 剛 (やまもとつよし)所属:ニューキャスト

「Grails徹底入門」9-11章、書きました。 Grails Acegi Plugin作った人。

ブログhttp://xmldo.blogspot.com/http://d.hatena.ne.jp/mottsnite/

こっちがメインかも

Page 3: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

おさらい

Page 4: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grailsとは?よく聞く説明「Groovyで実装されたRuby on Rails」!?  Java+Groovyで実装された、CoC、DRYの概念を取り入れた(‘RoR’にインスパイアされた)、Webアプリケーション開発環境。基礎はJavaでの開発で信頼されたSpring,Hibernate等を使用している。そして、それらをシンプルに利用できる環境。

Grails, the Platform (DGG2引用)

合ってるようで間違い

Page 5: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grailsの構成図GrailsGrailsGrails Groovy

Spring Hibernate SiteMeshGroovy

基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)JVMJVMJVMJVM

Hibernate:ORマッピング Spring: DIコンテナ・多機能なラッパーフレームワーク SiteMesh:レイアウトフレームワーク Jetty: サーブレットコンテナ HSQLDB:ピュアJavaなデータベース

Page 6: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

デモgrails create-app democd demograils create-domain-class Bookgrails create-controller Bookgrails run-appブラウザで開く--止める--

grails install-plugin acegi--プラグインインストールは前より早くなった!! ※要ネットワーク

Page 7: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grails-1.1

Page 8: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grails-1.1リリースJava5以上での動作Ant+IvyとMavenビルドのサポートスタンドアロンGORMプラグインの新機能:グローバルプラグイン、他動推移的なプラグイン解決、ローカルリポジトリー対応、他Springネームスペースサポート劇的に向上したパフォーマンステストフレームワークMVCレイヤーとGORM等のGrailsコアへの多くの新機能と改善

Groovyは最新の1.6に更新

CIとかに!

Springな人へ!

チーム!?

マジ!?

Page 9: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grailsの構成図GrailsGrailsGrails Groovy

Spring Hibernate SiteMeshGroovy

基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)JVMJVMJVMJVM

Hibernate:ORマッピング Spring: DIコンテナ・多機能なラッパーフレームワーク SiteMesh:レイアウトフレームワーク Jetty: サーブレットコンテナ HSQLDB:ピュアJavaなデータベース

2.5.6

3.3.1 2.4

6.1.14

1.8.0.5

1.5

1.5

Page 10: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

各APIのバージョン1.0.5 → 現在

hibernate-3.2.6.ga → hibernate-3.3.1jetty-6.1.12 → jetty-6.1.14spring-2.5.6 → spring-2.5.6sitemesh-2.3 → sitemesh-2.4hsqldb-1.8.0.5 → hsqldb-1.8.0.5groovy-all-1.5.6 → groovy-all-1.6.3-SNAPSHOT

Page 11: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

長くなるので、

一気に紹介。

Page 12: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

GORMイベント - イベントbeforeInsert,beforeUpdate,beforeDeleteに、さらにafterInsert, afterUpdate , afterDeleteが追加された。他に、 基本型(String,Integer)、 Enum でのコレクション。読み取りのみのオブジェクト取得。ソートのデフォルト値の設定。バッチフェッチ。ダイナミックファインダの向上。joinTable!generatorの指定

GORMスタンドアロンでGORMが使用可能!  Spring MVCでのサンプル、GRAILS_HOME/samples/petclinic-mvcを参照applicationContext.xmlにデータソースと、<gorm:sessionFactory/>の定義

<gorm:sessionFactory base-package="org.grails.samples" data-source-ref="dataSource" message-source-ref="messageSource">

<property name="hibernateProperties"><util:map>

<entry key="hibernate.hbm2ddl.auto" value="update"/>

</util:map></property>

</gorm:sessionFactory>

import

grail

s.pers

istenc

e.Enti

ty

@Entit

y

class

Person

{

String

name

...

}

Person

.groov

y

def book = Book.read(1)

static hasMany = [name:Str

ing]

static mapping = { sort "name" books sort:"title"}

static mapping = {batchSize 15

}

static mapping = {id generator:"org.hibernate.id.enhanced.SequenceStyleGenerator",

params:[sequence_name:'item_id_seq',initial_value:1000,increment_size:1]}

Page 13: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

GSP(Groovy Server Pages)GSPでのJSPタグライブラリのサポート

テンプレートネームスペース

Server Side Includes - <g:include>タグで別のコントローラ、アクションを呼び出せる。

パフォーマンスの改善

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

JSPタグを使う!<fmt:formatNumber value="${10}" pattern=".00"/>

メソッドのように使う!${fmt.formatNumber(value:10, pattern:".00")}

_tableRow.gspの中身<tr> <td class="prop">${label}</td> <td class="value">${value}</td></tr>ネームスペースtmpl+”_”を無くしたファイル名で呼び出す。<tmpl:tableRow label="one" value="two" />

<g:include controller="book" action="list"/>

コントローラあるいはタグライブラリでは、メソッドとして呼出も可能!def content = include(controller:"book", action:"list")

Page 14: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

データバインディングサブセットプロパティ

コレクション型への対応

今までは、以下の方法で全プロパティがバインドされました。person.properties = params

サブセットプロパティの対応で、指定した項目のみバインドも!person.properties["firstName","lastName"] = params

同じ方法でアクセスも可能!person.properties["firstName","lastName"].each { println it }

<g:textField name="books[0].title" value="the Stand" /><g:textField name="books[1].title" value="the Shining" /><g:textField name="books[2].title" value="Red Madder" />自動的に収集してまとめてくれます。

Page 15: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

コントローラ関連RESTfulマッピングの指定方法の向上  "/books"(resource:"book") の指定で、  GET, PUT, POST, DELETEを自動的に、 アクション"show", "save", "update", "delete"に設定多重サブミット対策フォームに、<g:form useToken="true">を指定すると、コントローラ内で、withFormを使用してフォームの多重サブミットを判別できるようになった。

リクエストのフォワード

エラーハンドルの宣言 UrlMappingsにエラーハンドルの宣言が可能に。

withForm { // 正常なリクエスト}.invalidToken { // ダブルクリックしたな?}

forward controller:"home", action:"index"

"500"(controller:"errors", exception:IllegalArgumentException)

Page 16: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Scaffoldingダイナミックスカッフォルディングとテンプレートダイナミックスカッフォルディング時のテンプレートは、grails install-templates コマンドでインストールされたテンプレートを使用するようになった。ダイナミックなのに微調整できる!スカッフォルドでのM-to-M対応!

Page 17: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

その他Maven統合Ant + Ivy統合 - Grailsが生成するAntのbuild.xmlとivy.xmlで、Grailsがインストールされていない環境(CIサーバ等)でもビルド可能。Log4j DSLEnvironment(環境) 、Metadata(メタ情報) API

非インタラクティブモード BeanBuilderでSpringネームスペースに対応テストフレームワーク - Testingプラグインは、本体に統合!Encrypted Data Sources - データソースパスワードの暗号化

grails.util.En

vironment.DEVE

LOPMENT

def metadata =

grails.util.M

etadata.curren

t

println metada

ta.application

Name

Page 18: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

まだまだ有ります。

ここからは、

チーム開発に便利!?な・・

Page 19: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

BuildConfig.groovyプロジェクトのビルドに関連する情報をカスタマイズできる定義ファイルGrails-1.0.x系では、Grailsのコンパイルされたクラスなどは、$USER_HOME/.grails/<バージョン>/以下に固定されていましたが、Grails-1.1からは指定変更可能になりました。

ファイルの設置場所 $PROJECT_HOME/grails-app/conf/BuildConfig.groovy中はこんな感じ↓

grails.project.plugins.dir="work_tmp/plugins"grails.project.work.dir="work_tmp/work"grails.plugin.location."feeds"="./plugins/feeds-1.4"

Page 20: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

BuildConfig定義できる内容※主な項目のみgrails.project.work.dir プロジェクトの作業ディレクトリ (このディレクトリ以下に classes,resources,plugins等が配置される) デフォルト:$USER_HOME/.grails/<バージョン>/projects/<プロジェクト名>/ 作業ディレクトリ以下を個別に指定も可能grails.project.plugins.dir プラグインのディレクトリ。 grails-1.0.xでの、$PROJECT_HOME/plugins デフォルト:$USER_HOME/.grails/<バージョン>/projects/<プロジェクト名>/pluginsgrails.project.test.reports.dir テストリポート書きだし先。grails.project.class.dir クラスの書きだし先。

Page 21: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

何でBuildConfigで設定変える必要があるの?個人的な意見・・・。grails.project.class.dirのように、コンパイルクラスを置く場所はよいとして、Grails-1.1からプラグインの場所が変わってしまったので、Grails-1.0.xを使っていたユーザには、プラグインのディレクトリが近くにいないのは・・・・。で、 grails.project.plugins.dirで場所を変更すると、プラグインの場所が近くで管理できるのでわかりやすい。ビルドサーバなどでの事情もあるし!

変な所にファイル置かれても・・

じゃあ、変えられればOKでしょ!

管理できるのは良いこと!

Page 22: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

プラグイン個別のパス指定プラグインを個別に指定することもできます。

プラグイン開発に便利!

grails.plugin.location."ext"="./plugins/ext-0.1"grails.plugin.location."form-maker"="./plugins/form-maker-0.1"grails.plugin.location."rhino"="./plugins/rhino-0.1.1"grails.plugin.location."waku-script"="./plugins/waku-script-0.2-SNAPSHOT"grails.plugin.location."yui"="./plugins/yui-2.6.0"grails.plugin.location."resources"="./plugins/resources-0.1"grails.plugin.location."taggin"="/works/experiment/grails-taggin/trunk"

チームメンバ

ーが

間違えなくて

良いね!

Page 23: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

どの辺がチーム開発?

で、ここで強引に

プラグインの話!

Page 24: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grailsプラグインとは?自分のプロジェクトに便利な拡張機能を追加できる

公式プラグインも有ります!ユーザ認証機能とか、メールとか、

コマンド install-pluginで簡単に追加できるそもそもGrails自身がプラグインの集合体!通常のGrailsプロジェクトと構造が同じ!~GrailsPlugin.groovyファイルの有無

詳しくは!

Page 25: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

ん?各機能をプラグイン分けすると、開発を分担できそうだ!

メインプロジェクト

プラグインA (プロジェクトの一部の機能)

グラフ機能プラグイン (今後も再利用できそうな機能)

ユーザ認証プラグイン (公式のプラグイン+カスタマイズ)

プラグインB (プロジェクトの一部の機能)

インストール

インストール

インストール

インストール

この辺がチーム開発!+再利用性!

Page 26: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

前から有るのに、何故いまさら主張するの?Grails-1.0.xでの問題点他のメンバーがさわってしまったりして・・・すぐさわれるので、ついカスタマイズ・・・プラグインの派生が・・・

Page 27: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCYEMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCYEMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCYEMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCYEMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY

EMERGENCY EMERGENCY

EMERGENCY中身が変わってるかもね!

オリジナルかわからないね!

管理しにくい!

Page 28: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

そこで!

Page 29: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grails-1.1からの、プラグインの新機能グローバルプラグイン複数のプラグインリポジトリ他動的なプラグイン自動解決 (Automatic Transitive Plugin Resolution)プラグインでのモジュール式アプリケーション開発プラグインスコープと環境定義

Page 30: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

グローバルプラグイン"-global"オプションを指定することによって、プラグインはグローバルプラグインとして管理されます。インストールされたプラグインは、同じ場所に保管されて、一度インストールすれば、同じバージョンのGrailsで他のアプリケーション開発するときは再度インストールすることなく使用することができます。

grails install-plugin acegi -global

Page 31: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

グローバルは、

必ず毎回とりこまれる!?

有る意味便利だけど...

・・・物によっては不便!? orz

Page 32: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

そんなあなたにこんな新機能!プラグインでのモジュール式アプリケーション開発他動的なプラグイン自動解決 (Automatic Transitive Plugin Resolution)複数のプラグインリポジトリ

Page 33: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

プラグインでのモジュール式アプリケーション開発Grails-1.1からプラグインは基本的にapplication.propertiesにメタ情報で管理されます。

プラグインの追加削除、バージョン変更は、プロジェクトのapplication.propertiesの内容を変更するだけでよいのです。これで、他のチームメンバーへのプラグイン変更通知も楽々。

app.version=0.1plugins.acegi=0.5.1app.servlet.version=2.4app.grails.version=1.1-SNAPSHOTplugins.hibernate=1.1-beta3app.name=relationsample plugins

.プラグイン名=バージョン

リポジトリに投げれば

Page 34: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

しかも!

Page 35: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

他動的なプラグイン自動解決他動的なプラグイン自動解決 (※仮翻訳) (Automatic Transitive Plugin Resolution)

application.propertiesの情報を元に、プラグインリポジトリから、自動的にバージョン確認して、インストール、アンインストールを行ってくれます。

間違った操作を防げます! チームメンバ

ーが

間違えなくて

良いね!

但し、run-appを2回!

Page 36: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

¿これって、

公式プラグインリポジトリの

プラグインにしか

対応していないんぢゃん?¿!¿El depósito sólo oficial?

Page 37: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

複数のプラグインリポジトリGrails-1.1から独自のプラグインリポジトリを設定することができるようになりました。設定方法USER_HOME/.grails/settings.groovy 又は、grails-app/conf/BuildConfig.groovyに情報定義。例えば、チームのプラグインリポジトリに使用するSVNのUrlが、"http://127.0.0.1/gp"だとしたらgrails.plugin.repos.discovery.local="http://127.0.0.1/gp" grails.plugin.repos.distribution.local="http://127.0.0.1/gp"

grails.plugin.repos.discovery.リポジトリ名称="リポジトリへのHttpベースのURL"grails.plugin.repos.distribution.リポジトリ名称="リポジトリへのHttpベースのURL"

Page 38: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

複数のプラグインリポジトリ独自のプラグインリポジトリ設定をすることによって、プラグイン関連のコマンドlist-plugins,install-pluginで設定したプラグインリポジトリも同時に参照してくれます。個別に参照する場合は、以下のように設定したリポジトリ名称を指定します。

grails list-plugins -repository=リポジトリ名称

Page 39: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

独自のプラグインリポジトリにプラグインをリリース

プラグインプロジェクトディレクトリでrelease-pluginに-repository=対象リポジトリ名称を指定して実行。

以下の内容を行ってくれます。1. プラグインのパッケージング2. プラグインリポジトリへのプラグインの追加 (grails-プラグイン名の階層に、tags trunkを追加)

3. プラグインのバージョンを自動でタグ切り4. プラグインリポジトリにある、プラグイン管理の .plugin-meta/plugins-list.xmlを更新

grails release-plugin -repository=リポジトリ名称

Page 40: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

チーム用の

プラグインリポジトリ!

Page 41: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grails-1.1は

いろいろ、便利。

Page 42: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

元々

メインプロジェクト

プラグインA (プロジェクトの一部の機能)

グラフ機能プラグイン (今後も再利用できそうな機能)

ユーザ認証プラグイン (公式のプラグイン+カスタマイズ)

プラグインB (プロジェクトの一部の機能)

インストール

インストール

インストール

インストール

Page 43: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

これから!Grails公式プラグイン

チーム用プラグインリポジトリ

メインプロジェクト

使用するプラグインの情報を

定義 プラグインA (プロジェクトの一部の機能)

グラフ機能プラグイン (今後も再利用できそうな機能)

ユーザ認証プラグイン (公式のプラグイン+カスタマイズ)

プラグインB (プロジェクトの一部の機能)

チーム用リポジトリ

独自プラグインリポジトリで管理

チームメンバー

チェックアウト

プラグイン自動解決

プラグイン自動解決

プラグイン

メタ情報で自動管理

プラグイン

Page 44: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

まとめapplication.propertiesにプラグイン情報を保持するため、チームメンバー間でのプラグインバージョン管理が楽に!BuildConfig.groovyで、開発時のビルド場所や、プラグイン情報をまとめやすくなった。見えないゴミ減る!プラグイン開発時のソース分けが以前より楽に!

開発プロジェクト内容の切り分けをプラグイン別にし、 チーム用プラグインリポジトリを活用することで、開発した内容をプラグインとしての再利用が期待できる!

Page 45: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grails-1.1.1

Page 46: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Grails 1.1.1GAE/Jの対応

Grails-1.1のバグフィックス&機能向上

Groovy 1.6.3

試したから、ブログみてね!

ぉぉ!

250件くらい!

Page 47: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

Q&A

Page 48: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

HQL派?

Criteria派?

Page 49: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

ROOは試しましたか?

Page 50: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

予告!

Page 51: Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo

次回

ビーンビルダー!?

まだ未定ですが…