Upload
tsuyoshi-yamamoto
View
2.016
Download
0
Embed Size (px)
Citation preview
G*とGAE/JGrails/GroovyでのAppEngine
名前:山本 剛 (やまもとつよし)所属:株式会社ニューキャストテクニカル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
Grails
Grailsとは・・・JavaEEで実績のあるSpringフレームワークやHibernateをベースに、Groovyを活用して効率よくJavaEE開発を行うことのできるフルスタックフレームワークです。
JVM
開発フレームワーク・DSL
Warファイルをデプロイ
Grails コア (Java+Groovyで実装)
Webコンテナ Testing コード生成
Grails プラグイン
プロダクション
何故Grails?利点DRY、CoC (この辺の話は詳しい人にお願いするとして・・・)DSLでのわかりやすいコード豊富なプラグインでサクサク開発各種機能、Web開発に必要なパーツ認証、AJAX、Flex、JMS、AppEngine、UI関連等。
プラグインでモジュラな開発。欠点ダイナミック過ぎて純粋なJEEアプリよりは・・・。ダイナミックすぎてエラーのポイントがわかりにくい。
Grailsプロジェクトがほぼそのままプラグイン化できるのでCMS的な感覚も持ち合わせている。
Groovy
つか、Groovyて何?
食べ物?おいしいの?
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()); }}
拡張子変更
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()); }}
セミコロントルツメ
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いなくなれ!
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()) }} メインなんて外にいっちゃえ!
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もいらんよ
Java から Groovy え!?HelloWorld.groovy
class HelloWorld { String name def greet(){ return "Hello "+name }}
def helloWorld = new HelloWorld()helloWorld.setName("Groovy")println(helloWorld.greet()) わかりやすく!
setとか無くていいメソッドの()省略
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にして!
Java から Groovy え!?HelloWorld.groovy
class HelloWorld { String name def greet(){ "Hello $name"}}
def helloWorld = new HelloWorld()helloWorld.name = "Groovy"println helloWorld.greet()
デフォルトコンストラクタも勝手にできるよ!
Java から Groovy え!?HelloWorld.groovy
class HelloWorld { String name def greet(){ "Hello $name"}}
def helloWorld = new HelloWorld(name: "Groovy")println helloWorld.greet()
Javaを使ってるなら、Groovy使うべき!!
つまり、GroovyではJavaコードの98%くらいは、そのまま動くので、Javaプログラマに言語を覚えるコストがあまりかからない。そしてGroovyな記述をすれば余分なものが無くなって見やすくわかりやすく。
他にもいろいろ...配列、 マップdef arr = [1,2,3,'hoge']def map = [a:1,b:2,c:'hoge']
クロージャ、Range、使いやすい正規表現イテレータ、each,collect,find ...メタプログラミング...... more!
あそんでみてね!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レポから勝手にとってくるんだからね!
Grailsと
AppEngine
お詫び。
Grails-1.2.0はリリースされましたが、今回必要なGAE/J対応の部分が年明けに先送り!なので・・・
今回は
Grails-1.1.1使います!
Grails-1.2では。ドメインクラス grails-app/domain にJPAアノテーション利用可になった。なのでドメインは、non-app-engineなドメインを、物によっては、そのまま再利用可能。パフォーマンス向上。動作速度が1.1.x系の2倍。GSPプリコンパイルでPermGenが減少。1秒間のリクエスト処理 PermGenが減少
GAE/J+Grailsにも、うれしい内容!
でわ開始!コピれるよ。
http://gist.github.com/263610
Step.1Grailsインストール!環境変数設定export GRAILS_HOME=/インストールパス(解凍先)export PATH=$GRAILS_HOME/bin:$PATH
GAE SDK for Java ダウンロード
環境設定export APPENGINE_HOME=/インストールパス(解凍先)
GAEに新規アプリ作成!
Step.2Grailsでアプリケーション作ってみる新規プロジェクト作成
ドメインクラス作成
コントローラ作成
grails create-app myappcd myapp
grails create-domain-class jp.grails.Todo
grails create-controller jp.grails.Todo
やってみよう!
コピれるよ。http://gist.github.com/263610
Step.3GAE/Jに対応させる。プラグインインストールConfig.groovy 設定調整
Grails GAE/J用プラグイン
AppEngine プラグインGORM-JPA プラグイン
AppEngine プラグインGrailsをGAE/Jに対応させるプラグインhttp://www.grails.org/plugin/app-engine機能インストール時にGAEに必要なファイル生成デプロイ用のコマンドスカッフォルドテンプレートJDOとJPAに対応ユーザ認証設定 Config.groovy
grails install-plugin app-engine途中でjpa/jdoどちらを使うか質問されるので、今回は”jpa”と入力
GORM-JPA プラグインhttp://grails.org/plugin/gorm-jpaできること
GORMと同じsave(),list()等のメソッドが利用できる。(※一部未対応、)
できないことドメインクラスと同じmapping定義ドメインの定義には、JPAアノテーションを利用Criteria (※JPA1.0で未対応なため)
grails install-plugin gorm-jpa
Config.groovy 設定調整app engineでのアプリケーション名の指定1. grails create-appで新規作成時に指定した名称がapp engineでのアプリケーション名になる。2. grails-app/conf/Config.groovy に指定もできる。
google.appengine.application="mygaeapp"
Step.4GAE/Jに対応させる。ドメインクラス→JPA化微調整用スクリプト
ドメインクラス→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
(現状の) 問題点app engine 1.2.6からの問題
id:uehajさんのブログ(Grな日々)を参考にリンクを参照。http://tinyurl.com/yfzx94t
要約Grailsで最適化に使用されているStringCharArrayAccessor が問題なのでシステムプロパティを設定すればどうにかなるぉ。
s/Groovy/Grails/
stringchararrayaccessor.disabled=true
キタコレ
プラグイン改造!
app-engineプラグインと、appengine-web.xmlと、アプリ。
結論から!appengine-web.xml にシステムプロパティを追加するには、どうやらプラグインを改造しなくてはならない。なぜかここはテンプレートになっていない
改造プラグイン好ましくない・・・。
http://jira.codehaus.org/browse/GRAILSPLUGINS-1392
テンプレ化。早期対応に期待
app-engineプラグインと、appengine-web.xmlと、アプリ。
非公式改造方法。1. プラグインをプロジェクトディレクトリに移動BuildConfig.groovy
2. 対象のファイルを探して編集_Events.groovy
3. 改造されたプラグインと共に生きる覚悟。
grails.project.plugins.dir="plugins"
No!
スマートな方法!
スマートな方法!Grailsではコマンドスクリプトのイベントを拾えます。scripts/_Events.groovy詳しくはGrails徹底入門 第11章をみてね!
app-engineプラグインのスクリプトが終わった後のイベントでappengine-web.xmlを編集すればいい!(groovyなXMLの処理で!)
app-engineプラグインと、appengine-web.xmlと、アプリ。
11章を参考に!
_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
Step.5ローカル起動デプロイ
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
おさらい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
次期バージョンに期待Grails-1.2 + app-engineプラグイン。
まとめGrailsでのAppEngine対応基本はプラグインでOKapp-enginegorm-jpanon-GAE/JなGrailsアプリケーションとの差分をプラグインが吸収するスタイル。再利用性を考えている。
Grails経験者であれば、かなりわかりやすい。注意点まだまだ発展途上です。思い通りにならない。