48
G*とGAE/J Grails/GroovyでのAppEngine

名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Embed Size (px)

Citation preview

Page 1: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

G*とGAE/JGrails/GroovyでのAppEngine

Page 2: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

名前:山本 剛 (やまもとつよし)所属:株式会社ニューキャストテクニカルDTP。

Web案件の80%はGrailsを使用。Strutsを使ってた時代に比べると、柔軟で再利用性の高い開発ができてる。

JGGUG(じぇいがぐ) 名古屋支部長です。「Grails徹底入門」9-11章を書きました。 公式プラグインGrails Acegi Plugin チームメンバーhttp://d.hatena.ne.jp/mottsnite/twitter @tyama

自己紹介 JGGUGjapan grails/groovy user group

Page 3: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Grails

Page 4: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Grailsとは・・・JavaEEで実績のあるSpringフレームワークやHibernateをベースに、Groovyを活用して効率よくJavaEE開発を行うことのできるフルスタックフレームワークです。

JVM

開発フレームワーク・DSL

Warファイルをデプロイ

Grails コア (Java+Groovyで実装)

Webコンテナ Testing コード生成

Grails プラグイン

プロダクション

Page 5: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

何故Grails?利点DRY、CoC (この辺の話は詳しい人にお願いするとして・・・)DSLでのわかりやすいコード豊富なプラグインでサクサク開発各種機能、Web開発に必要なパーツ認証、AJAX、Flex、JMS、AppEngine、UI関連等。

プラグインでモジュラな開発。欠点ダイナミック過ぎて純粋なJEEアプリよりは・・・。ダイナミックすぎてエラーのポイントがわかりにくい。

Grailsプロジェクトがほぼそのままプラグイン化できるのでCMS的な感覚も持ち合わせている。

Page 6: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Groovy

Page 7: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

つか、Groovyて何?

食べ物?おいしいの?

Page 8: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.java

public class HelloWorld { String name; public void setName(String name){ this.name = name; } public String getName(){ return name; } public String greet(){ return "Hello "+name; } public static void main(String[] args){ HelloWorld helloWorld = new HelloWorld(); helloWorld.setName("Groovy"); System.out.println(helloWorld.greet()); }}

拡張子変更

Page 9: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

public class HelloWorld { String name; public void setName(String name){ this.name = name; } public String getName(){ return name; } public String greet(){ return "Hello "+name; } public static void main(String[] args){ HelloWorld helloWorld = new HelloWorld(); helloWorld.setName("Groovy"); System.out.println(helloWorld.greet()); }}

セミコロントルツメ

Page 10: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

public class HelloWorld { String name public void setName(String name){ this.name = name } public String getName(){ return name } public String greet(){ return "Hello "+name } public static void main(String[] args){ HelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") System.out.println(helloWorld.greet()) }}

getterとsetterいなくなれ!

Page 11: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

public class HelloWorld { String name public String greet(){ return "Hello "+name } public static void main(String[] args){ HelloWorld helloWorld = new HelloWorld() helloWorld.setName("Groovy") System.out.println(helloWorld.greet()) }} メインなんて外にいっちゃえ!

Page 12: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

public class HelloWorld { String name public String greet(){ return "Hello "+name }}

HelloWorld helloWorld = new HelloWorld()helloWorld.setName("Groovy")System.out.println(helloWorld.greet())

publicとかもいぢるSystem.outもいらんよ

Page 13: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

class HelloWorld { String name def greet(){ return "Hello "+name }}

def helloWorld = new HelloWorld()helloWorld.setName("Groovy")println(helloWorld.greet()) わかりやすく!

setとか無くていいメソッドの()省略

Page 14: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

class HelloWorld { String name def greet(){ return "Hello "+name }}

def helloWorld = new HelloWorld()helloWorld.name = "Groovy"println helloWorld.greet()

returnもいらない!+nameも””の中に$nameにして!

Page 15: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

class HelloWorld { String name def greet(){ "Hello $name"}}

def helloWorld = new HelloWorld()helloWorld.name = "Groovy"println helloWorld.greet()

デフォルトコンストラクタも勝手にできるよ!

Page 16: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Java から Groovy え!?HelloWorld.groovy

class HelloWorld { String name def greet(){ "Hello $name"}}

def helloWorld = new HelloWorld(name: "Groovy")println helloWorld.greet()

Page 17: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Javaを使ってるなら、Groovy使うべき!!

つまり、GroovyではJavaコードの98%くらいは、そのまま動くので、Javaプログラマに言語を覚えるコストがあまりかからない。そしてGroovyな記述をすれば余分なものが無くなって見やすくわかりやすく。

Page 18: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

他にもいろいろ...配列、 マップdef arr = [1,2,3,'hoge']def map = [a:1,b:2,c:'hoge']

クロージャ、Range、使いやすい正規表現イテレータ、each,collect,find ...メタプログラミング...... more!

Page 19: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

あそんでみてね!Groovy-1.7で、twitter4j使ったサンプル

@Grab('net.homeip.yusuke:twitter4j:[2.0,)')import twitter4j.*def user="username",pass="pass"new Twitter(user,pass).friendsTimeline.each { println "${it.user.name}: ${it.text}"}

ライブラリーもmavenレポから勝手にとってくるんだからね!

Page 20: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Grailsと

AppEngine

Page 21: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

お詫び。

Grails-1.2.0はリリースされましたが、今回必要なGAE/J対応の部分が年明けに先送り!なので・・・

Page 22: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

今回は

Grails-1.1.1使います!

Page 23: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Grails-1.2では。ドメインクラス grails-app/domain にJPAアノテーション利用可になった。なのでドメインは、non-app-engineなドメインを、物によっては、そのまま再利用可能。パフォーマンス向上。動作速度が1.1.x系の2倍。GSPプリコンパイルでPermGenが減少。1秒間のリクエスト処理 PermGenが減少

GAE/J+Grailsにも、うれしい内容!

Page 24: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

でわ開始!コピれるよ。

http://gist.github.com/263610

Page 25: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Step.1Grailsインストール!環境変数設定export GRAILS_HOME=/インストールパス(解凍先)export PATH=$GRAILS_HOME/bin:$PATH

GAE SDK for Java ダウンロード

環境設定export APPENGINE_HOME=/インストールパス(解凍先)

GAEに新規アプリ作成!

Page 26: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Step.2Grailsでアプリケーション作ってみる新規プロジェクト作成

ドメインクラス作成

コントローラ作成

grails create-app myappcd myapp

grails create-domain-class jp.grails.Todo

grails create-controller jp.grails.Todo

Page 27: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

やってみよう!

コピれるよ。http://gist.github.com/263610

Page 28: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Step.3GAE/Jに対応させる。プラグインインストールConfig.groovy 設定調整

Page 29: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Grails GAE/J用プラグイン

AppEngine プラグインGORM-JPA プラグイン

Page 30: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

AppEngine プラグインGrailsをGAE/Jに対応させるプラグインhttp://www.grails.org/plugin/app-engine機能インストール時にGAEに必要なファイル生成デプロイ用のコマンドスカッフォルドテンプレートJDOとJPAに対応ユーザ認証設定 Config.groovy

grails install-plugin app-engine途中でjpa/jdoどちらを使うか質問されるので、今回は”jpa”と入力

Page 31: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

GORM-JPA プラグインhttp://grails.org/plugin/gorm-jpaできること

GORMと同じsave(),list()等のメソッドが利用できる。(※一部未対応、)

できないことドメインクラスと同じmapping定義ドメインの定義には、JPAアノテーションを利用Criteria (※JPA1.0で未対応なため)

grails install-plugin gorm-jpa

Page 32: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Config.groovy 設定調整app engineでのアプリケーション名の指定1. grails create-appで新規作成時に指定した名称がapp engineでのアプリケーション名になる。2. grails-app/conf/Config.groovy に指定もできる。

google.appengine.application="mygaeapp"

Page 33: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Step.4GAE/Jに対応させる。ドメインクラス→JPA化微調整用スクリプト

Page 34: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

ドメインクラス→JPA化ドメインクラス編集。

スカッフォルド。grails generate-all jp.grails.Chat

@Entityclass Chat implements Serializable {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY) Long id

@Column String message...省略...

JPAのアノテーション...通常はこんな感じ...class Chat { String message ...省略...

app-engineプラグインのテンプレートから生成される

http://gist.github.com/263511

Page 35: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

(現状の) 問題点app engine 1.2.6からの問題

id:uehajさんのブログ(Grな日々)を参考にリンクを参照。http://tinyurl.com/yfzx94t

要約Grailsで最適化に使用されているStringCharArrayAccessor が問題なのでシステムプロパティを設定すればどうにかなるぉ。

s/Groovy/Grails/

stringchararrayaccessor.disabled=true

Page 36: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

キタコレ

プラグイン改造!

Page 37: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

app-engineプラグインと、appengine-web.xmlと、アプリ。

結論から!appengine-web.xml にシステムプロパティを追加するには、どうやらプラグインを改造しなくてはならない。なぜかここはテンプレートになっていない

改造プラグイン好ましくない・・・。

http://jira.codehaus.org/browse/GRAILSPLUGINS-1392

テンプレ化。早期対応に期待

Page 38: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

app-engineプラグインと、appengine-web.xmlと、アプリ。

非公式改造方法。1. プラグインをプロジェクトディレクトリに移動BuildConfig.groovy

2. 対象のファイルを探して編集_Events.groovy

3. 改造されたプラグインと共に生きる覚悟。

grails.project.plugins.dir="plugins"

Page 39: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

No!

Page 40: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

スマートな方法!

Page 41: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

スマートな方法!Grailsではコマンドスクリプトのイベントを拾えます。scripts/_Events.groovy詳しくはGrails徹底入門 第11章をみてね!

app-engineプラグインのスクリプトが終わった後のイベントでappengine-web.xmlを編集すればいい!(groovyなXMLの処理で!)

app-engineプラグインと、appengine-web.xmlと、アプリ。

11章を参考に!

Page 42: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

_Events.groovyapp-engineプラグインと、appengine-web.xmlと、アプリ。

import groovy.xml.StreamingMarkupBuilderimport groovy.xml.MarkupBuilder

includeTargets << new File("${appEnginePluginDir}/scripts/_AppEngineCommon.groovy")

eventStatusFinal = { msg -> def appXmlFile = new File("$stagingDir/WEB-INF/appengine-web.xml") def xml = new XmlSlurper().parse(appXmlFile) xml."system-properties".appendNode { property(name:"stringchararrayaccessor.disabled",value:"true") } def smb = new StreamingMarkupBuilder() def result = smb.bind{ mkp.declareNamespace("":"http://appengine.google.com/ns/1.0") mkp.yield xml } new FileOutputStream(appXmlFile).withWriter('UTF8'){w-> w << result }}

<appengine-web-app xmlns='http://appengine.google.com/ns/1.0'><application>jggugv4</application><version>2</version><sessions-enabled>true</sessions-enabled><ssl-enabled>true</ssl-enabled><system-properties><property name='stringchararrayaccessor.disabled' value='true'/>

</appengine-web-app>

http://gist.github.com/263509

Page 43: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Step.5ローカル起動デプロイ

Page 44: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

GAE/JでGrailsを動かすローカル起動

デプロイ

問題があり以下のコマンドは使えない(GAE SDK側の問題っぽい)

$ grails app-engine run

バージョン設定をする。 = GAEでのバージョン管理grails set-version 1

GAE用のパッケージ生成grails app-engine package

GAE SDKのコマンドでデプロイ$APPENGINE_HOME/bin/appcfg.sh update ./target/war

grails app-engine deploy

Page 45: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

おさらいAPPENGINE_HOMEの設定export APPENGINE_HOME=/opt/appengine-java-sdk-1.3.0

プラグインインストールgrails install-plugin app-enginegrails install-plugin gorm-jpa

ローカル起動grails app-engine run

バージョン設定とパッケージングgrails set-version 1grails app-engine package

GAE SDKのコマンドでアップデート(デプロイ)$APPENGINE_HOME/bin/appcfg.sh update ./target/war

後は繰り返しgrails app-engine package$APPENGINE_HOME/bin/appcfg.sh update ./target/war

Page 46: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

次期バージョンに期待Grails-1.2 + app-engineプラグイン。

Page 47: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

まとめGrailsでのAppEngine対応基本はプラグインでOKapp-enginegorm-jpanon-GAE/JなGrailsアプリケーションとの差分をプラグインが吸収するスタイル。再利用性を考えている。

Grails経験者であれば、かなりわかりやすい。注意点まだまだ発展途上です。思い通りにならない。

Page 48: 名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン

Thank you.

日本 Grails/Groovy ユーザーグループhttp://www.jggug.org/