カスタム検索
ラベル grails の投稿を表示しています。 すべての投稿を表示
ラベル grails の投稿を表示しています。 すべての投稿を表示

2010年1月29日金曜日

kumofs その3・Grailsと連携してみた

Grailsからkumofsを使ってみます

・適当な Grails アプリケーションを作成します
grails create-app kvstest

・memcachedクライアントのライブラリをインストールします
kumofs は memcached プロトコルを使用します。
今回は memcached の Java クライアントである Spymemcached
を使用します

上記サイトからJARファイルをダウンロードして lib フォルダへコピーします


・やりとりをするサービスを作成します
IBMのサイトにとても良いサンプルがあるのでこれを参考にします
上記サイトにあるサービスがほぼそのまま使えます
setのタイムアウトが600と指定されているのですが、kumofsでは0しか受け付けないため、0に変更します

*デフォルトの接続方式だと大量データでエラーが起きたので変更しました、そこらへんは次回に。

->Spymemcachedの問題でした、解決方法はこちらのエントリーで

memcachedClient.set(key, 0, value)


・適当なコントローラーを作成してget,setをテストします
本当に適当なので割愛、SSだけ





サクっと動きました!
次回はCouchDBとの速度比較なんかをやってみます

2010年1月27日水曜日

コンパイルされたClassファイルからJavaのバージョンを取得する

Javaのバージョントラブルがあったので、忘れないうちにメモ!
ココを参考にしました。

javap -v ClassFile | grep major
(クラスファイル名に .class はなしでOK)

で以下のように表示される(はず)

major version: 47

Javaのバージョンとの対比表

1.1 = 45.3
1.2 = 46.0
1.3 = 47.0
1.4 = 48.0
1.5 = 49.0
1.6 = 50.0

なので、上記の場合は 1.3でコンパイルされている、と。
Grailsって中のファイルとPluginでコンパイルされるバージョンが違う・・・Javaの参照の仕方が違うのかな

2009年10月15日木曜日

Grails+postgresでDBチューニング

Grails+postgresでのチューニングで自分がやっている方法をざっくりとまとめ

・postgresからスロークエリの検出をする

postgresql.conf に設定

log_min_duration_statement = 5000ms

上記だと5秒以上かかった処理をログに書き出してくれます。
Hibernateから実行したクエリは以下のような感じで書き出されます。

LOG: duration: 7912.798 ms statement: EXECUTE [PREPARE: select book0_.id as book_1_ from BOOK book0_ where book0_.id=$1]

・クエリのコストを検出する

ログに出力されたクエリが実際にDBで検索にかかるコストを算出します。
SQLの部分( select ~)の前に explain をつけて実際にクエリを実行します。
($1,$2等は実際の値に置き換えて下さい。)

explain select book0_.id as book_1_ from BOOK book0_ where book0_.id=1

すると以下のような情報が帰ってきます。

Seq Scan on book this_ (cost=0.00..32955.18 rows=1 width=2104)
Filter: (id = 1)

0~32955のコストが予想されています。

・indexによるチューニングを行う

10000を超えるようなコストはかなりの負荷になりますので、indexをつけてやります。
(実際にはidにindexは必要ありません、検索対象となる名称とかに置き換えて下さい)

CREATE INDEX id_idx
ON book
USING btree
(id);

再度 explain 付きのクエリを実行すると、以下のような結果が帰ってきます。

Bitmap Heap Scan on book this_ (cost=4.64..98.43 rows=1 width=2104)
Recheck Cond: (id = 1)
-> Bitmap Index Scan on id_idx (cost=0.00..4.64 rows=1 width=0)
Index Cond: (id = 1)

検索対象のフィールドにIndexがついていたため、indexを使って検索し、総コストが 4.64~98.43 となります。
これであればサクサクと検索が実行されます :)

postgresを対象に書きましたが、MySQLでもOracleでもexplainはありますので同じような流れでチューニング可能です。

2009年9月14日月曜日

Spring tcServer 超入門!インストール編

GrailsがSpringFrameworkに買収され(今はそのSpringがVMWareに買収されましたが)、Springには元tomcatの中の人達が居るらしく
Groovy/Grailsを動かすにはtcServerが最適らしい
そんなわけでとりあえずインストールしてみた

まずは tcServer の構成から
tcServer = いわゆるインスタンす部分、中身はtomcat
AMS agent = 同PC内のtcServerをまとめる
serverのconfigはここで管理するっぽい

AMS Server = AMS agentをまとめる、apacheのかわりになる部分っぽい

AMS Serverを受け口としてAMS agentへ割り振り、agentがインスタンスを管理している、と・・・そんな感じでしょうか
Server hasMany Manager hasMany Instance な感じ、AMS Server自体は分散処理が必要なのかな・・・?

・まずはMacへインストールしてみる
tcServer-6.0.20.A-SR1-macosx-node.tgz をダウンロード
解凍して install.sh を実行
Macには AMS agent と tcServer とかしかない
どっちを入れるか聞いてくるので、とりあえず両方インストール

・tcServer Instanceを作成
cd tcServer-6.0
./tcserver-instance.sh -s testserver -v 6.0.20.A

testserverという名称で tomcat のバージョンは 6.0.20.A を指定
これで testserver フォルダと tomcat-6.0.20.A フォルダが出来る
デフォルトだと以下のポートが使用されるらしい
HTTP listen port: 8080
JMX port: 6969
AJP port: 8009
Shutdown port: -1

・testserverを起動
testserver/bin/tcserver-ctl.sh start

http://localhost:8080 にアクセスして tcServer の画面が出れば起動は成功

・アプリケーションの配備
単純にデプロイするだけなら testserver/webapps へwarをコピーすればOK

次回はAMSを使ったクラスタや自動デプロイ等に挑戦!

2009年9月4日金曜日

Grails 1.1.1でDomainのsaveについて

Grails1.1.1でたまに .save() でエラーが出る事があります。
MissingPropertyException for "save" って感じなのですが、saveはメソッドなのにプロパティー扱いされてます・・・

これがまた絶対起きる訳ではなく、同じコードでもcleanしたら発生したりしなかったりとやっかいなものです。
現在は修正済みらしく、1.1.2 or 1.2では直るようです。
JIRAはこちら

JIRAにも書いてありますが、HibernateGrailsPluginの初期化がうまくいってないようです。
回避方法としてはドメインの .count とか .list とかを使うと初期化がされるようで、Bootstrap.groovy に以下を追加すれば、
すべてのドメインを初期化してくれます。


import org.codehaus.groovy.grails.commons.ApplicationHolder

class BootStrap {
def init = { servletContext ->
// workaround for GRAILS-4580
ApplicationHolder.application.domainClasses.each { dc ->
dc.clazz.count()
}
}
}

2009年8月24日月曜日

fxugに参戦!

fxugの名古屋の第2回勉強会へスピーカーとして参加しました

内容は一からライブコーディングでGrails+BlazeDSの通信を実現するというものです。
今回はFlexのUserGroupと言う事でGrailsが受け入れられるのか若干不安でしたが、アンケート結果を軽く見せてもらったら思ったよりもGrailsへの関心をもっていただけ、楽しんでもらえたようで内心ホッとしております。
これを機にGrailsユーザが一人でも増えれば幸いです :)

今回個人的に興味をもったのが、FlashCatalystとFlashBuilder4です。
Catalystはイラレ(というと東京では怒られるらしい!?)で作ったaiファイルを読み込んで、入力フォームやらシーンやらアニメーションに動作やらを指定してやるとそのままFlashBuilderで読み込んでコンポーネントとして使えますよ!みたいなものです。
インターフェースと実装を完全に切り分けて作る事で、今までエフェクトの動作やシーンの切替(このボタン押すと詳細がここに表示されて〜みたいな感じの)をプログラマが実装していたのをデザイナー側でやれるという事です。

FlashBuilder4はRemoteObjectからウィザードでデータを取得してDataGrid等とマッピング、さらにマッピングしたオブジェクトからフォームを自動生成が出来るという新機能を実装しています。
これはなかなかおもしろいのですが、欲を言えばフォームの動的生成なんかが出来るともっと良いですね!

2009年7月12日日曜日

Grailsで簡単暗号化! Grails Codecを使ってみよう!

Grailsで暗号化をするのは凄く簡単です。
公式ドキュメントにも乗っていますが、Objectに encodeAsBase64() というのが注入されています。
複合は decodeBase64() を使います。

なので hoge を暗号化すると、以下のコードになります。

def key="hoge".encodeAsBase64() //暗号化
println key
println new String(key.decodeBase64()) //複合化


decodeBase64() では byte配列が返ってくるので、new Stringしてやると文字列として読み取れる形式になります。

これをGroovyだけでやると以下のようになります。

def bytes="hoge".getBytes()
def key=bytes.encodeBase64().toString()
println key
println new String(key.decodeBase64())


ところで、GrailsにはencodeAsBase64()以外にも色々なCodec(encode,decode出来るもの)が用意されています。
(encodeAsHTML()などはscaffoldしたgspにかかれていますね)
更にCodecは自分で追加する事が出来ます。
grails-app/utilsフォルダへ HogeCodec.groovy というファイルを追加し、 encode、decodeというStaticメソッドを用意します。
(Codecファイルを作るスクリプトがあってもいいと思うのですが見当たりませんでした・・・)


class HogeCodec {
static encode = { theTarget ->
return "hoge encode!!!"
}

static decode = { theTarget ->
return "hoge decode!!!"
}
}


これでObjectへ encodeAsHoge() と decodeHoge() が注入されます、簡単ですね!

2009年7月2日木曜日

Grails/Groovy勉強会やります

JGGUGの第2回名古屋支部イベント「Grails/Groovy勉強会」でスピーカーをやる事になりました。

詳細はこちら

「Grailsで{さくさく}作るRIA」ですが、内容は入門編です。
続きも考えて居ますので、興味ある方は無料なんで是非ご来場下さい :)

2009年6月15日月曜日

Grails+MySQL Clusterでのトラブル

Grails+MySQL Clusterでのハマったのでメモメモ
(Grailsじゃなくても起こる問題なんだけども)

開発環境時はMyISAMでうまく行っていたのですが、サーバへアップした時にテーブルが作成出来ずにエラーとなりました。
何度やっても特定のテーブルだけが作成されなかったのでMyISAMで作成したDBをダンプアウトしてSQLで流し込んでみたら「Row size too large」だとかなんとか・・・

Google先生に聞いてみたら以下で同様なトラブル事例が
http://forums.mysql.com/read.php?25,33433,33433

Clusterではサイズ指定されたフィールドが 8052バイトを超えるとNGらしいです。

UTF-8では1文字3バイトなのでGrailsのDomain上で、
Stringのフィールドをmapping指定せずに作った場合 varchar(255) で1フィールド辺り768バイト使用されます。
なのでString指定のフィールドを作る場合は極力mappingを指定するようにしましょう。


class Book {
static mapping = {
name type:”text”
}

String name
}

2009年5月19日火曜日

Grails 1.1.1 でプラグインリポジトリ(認証付き)を使ってみた

Grails1.1.1がリリースされた事もあり、自分プラグインリポジトリを試してみました。

1.1系になり、プラグイン周りが大幅に変わったのはコチラで詳しく解説されています。


では早速実践です!(環境はMacです)


まずはSubversion Clientを1.5系にします(SVNKitの部分で1.5以外はうまく動作しませんでした)
ココから探っていくと過去のバージョンもありましたのでそこから 1.5.6 を入れました。

次にSVNリポジトリを作成します。リポジトリ側のバージョンは1.5でなくてもOKです。(今回は 1.4.2 でテストしました)
サーバ側の設定は何もありません、中身も空で良いです。

開発環境orプロジェクトへリポジトリ設定を追加します。
開発環境に追加する場合は ~/.grails/settings.groovy ファイルへ、
プロジェクト毎に設定する場合はプロジェクトの grails-app/conf/BuildConfig.groovy ファイルへ以下の内容を記述します。

grails.plugin.repos.discovery.リポジトリ名称=SVN URL
grails.plugin.repos.distribution.リポジトリ名称=SVN URL

discovery は取得(list-pluginsやinstall-plugin)、
distribution はコミット(release-plugin)の設定です。

開発環境とプロジェクトの両方に同じリポジトリ名称が設定されている場合はプロジェクトに設定された方が優先されます。

SVNのURLは認証が無い場合はそのまま、http://svnurl/ と記述すればOKですが、今回はBasic認証を使います。
Basic認証を使う場合には https を使用する必要があります。

試しに https://svnurl/ だけ指定して list-plugins するとユーザ名とパスワードを聞かれます。
ですが、これ list-plugins 以外にも run-app 等毎回聞かれます、しかもhttpsのリポジトリが複数あると、すべてのパスワードを毎回聞かれてうっとおしいことこの上ないです。(しかもパスワード入力がマスクされないので丸見えです :p)

ユーザを聞かれないようにするには https://username:password@svnurl と入力しておきます。
ですがこれもパスワード丸見えなので、BuildConfig.groovy に書いておくとチームで使うには不便です。
(とりあえずチーム内で使うには各自の settings.groovy へ書いておくのが得策と思われます)

ここまで設定出来れば準備完了です。
適当な plugin を作成し、releaseしてみましょう。

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

コミットメッセージ等を聞かれて、うまくいけばSVNへプロジェクトがコミットされます。
初releaseの場合はリポジトリに .plugin-meta/plugin-list.xml ファイルが作成されます。
この中にそのリポジトリ内のpluginの情報が記述されます。
ファイルがうまく作成されていたら以下のコマンドを実行して確認してみましょう。

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

先程releaseした testPlugin が表示されれば成功です。

ですが、今 release したローカルのファイルはsvnの管理下にいないので、次のバージョンをリリースするには、
一度アップされた plugin を checkout して、更新後、release-plugin する必要があります。
1回目だけはちょっと面倒です。

最後に通常のGrailsプロジェクトを作成し、insall-plugin 出来れば完璧です。

grails create-app test
cd test
grails install-plugin test-plugin

これでチーム開発をする時に plugin ファイルを共有する必要がなく、
application.properties に plugins.test-plugin=0.1 が記述されているだけで、ファイルがなければ run-app時に自動的にインストールしてくれます!

まだちょっと扱いが生な感じがするのですが機能としては十分使えそうです、プラグインもプロジェクトもスッキリさせましょう!

2009年5月12日火曜日

Grailsで添付ファイル付きメールを送る

Grailsには公式でMailPluginというのがあり、こいつを使うとDSL形式で簡単にメールが送れます。

ですが、こいつは添付ファイルに対応していません。
ここですでに解決が出ているのですが、公式のバージョンではまだ実装されていないので、自分で拡張してしまいましょう。

grails install-plugin mail
でpluginをインストールし、その中の MailService.groovy ファイルを開きます。

このファイルの中に MailMessageBuilder Class の定義がされているのですが、こいつがDSLを処理している部分になります。
(void to とか void title とかその辺りです。)
ここに attachBytes という添付ファイル名、コンテントタイプ、バイト配列を受け取ってメールに添付する処理を追加してやります。


void attachBytes(String fileName, String contentType, byte[] bytes) {
getMessage().mimeMessageHelper.addAttachment(fileName, new ByteArrayResource(bytes), contentType) }
}


このままだと getMessage した時に、以下の部分が呼ばれます


message = new MimeMailMessage(mailSender.createMimeMessage() )


添付ファイルを送る時は Multipart にしないといけないので、以下のように書き換えてやります

message = new MimeMailMessage(new MimeMessageHelper(mailSender.createMimeMessage(), true ))


あとはメール送信時に attachBytes を呼び出してやればOKです。

def file=new File("test.dat")
// ファイル名に日本語が含まれる場合は文字列をエンコードする必要があります
// 日本のメール環境では iso-2022-jp がまだまだ主流なので、iso-2022-jp を使いましょう
//def title=javax.mail.internet.MimeUtility.encodeWord("日本語ファイル名.dat", "utf-8", "B")
def title=javax.mail.internet.MimeUtility.encodeWord("日本語ファイル名.dat", "iso-2022-jp", "B")

// コンテントタイプはファイルや用途に合わせて変更して下さい
def contentType="application/octet-stream"

mailService.sendMail {
to "test@test.jp"
from "test@test.jp"
subject "添付テスト"
body "添付ファイルを送ります"
attachBytes title, contentType , file.readBytes()
}


と、思ったらMail from Grailsなんてページがあったり、この方法でもファイル添付出来るみたいですね。
↑プロポーザル的に書かれているだけで、実装されているわけではないらしいです

2009/5/13 追記
メールタイトルの文字コードと、Mail from Grailsのページについて、mottsniteの中の人から指摘があったので修正

2009年5月1日金曜日

Grailsで帳票! fop編

帳票、というか組版の部類になると思うんですが、fopでPDFを作成してみました。

帳票というと帳票ソフト+帳票ツールという概念が強かったのですが、
mottsniteさんから
「HTML組む時にGUIソフト使わないっしょ?帳票もGUI使わずにfopでタグ書いたらいいんじゃないの?」
と言われ妙に納得してしまったので、使ってみる事に。

日本語出力までに微妙な所でハマってしまったのでメモっておきます。

・まずはApache fopをダウンロードします。(0.95を使いました)

・Grailsのプロジェクトにライブラリを追加します。
buildフォルダから fop.jar と、libフォルダから以下のファイルを grails プロジェクトの lib フォルダにコピーします。
xmlgraphcs-commons-1.3.1.jar
batik-all.jar
avalon-framework-4.2.0.jar

その他のjarファイルはgrailsが持っているもので補えるので必要ありません。

・FOPの設定ファイルをコピーします
conf/fop.xconf ファイルを適当な場所にコピーして以下のように書き換えます。

<?xml version="1.0"?>
<fop version="1.0">
<base>.</base>
<source-resolution>72</source-resolution>
<target-resolution>72</target-resolution>

<default-page-settings height="11in" width="8.26in"/>

<renderers>
<renderer mime="application/pdf">
<filterList>
<value>flate</value>
</filterList>

<fonts>
<auto-detect/>
</fonts>

</renderer>
</renderers>
</fop>


昔のバージョンではフォントファイルからフォントメトリクスを作成し、その定義をちまちまと書く必要があったのですが、
今はfontsのauto-detectでOSがもってるTTFのフォントが使えるようになります。
(一回目の起動時はフォントファイルを全部読み込むので時間がかかります。)

・簡単なFoファイルを用意します

<?xml version="1.0" encoding="UTF-8" ?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="PageMaster">
<fo:region-body margin-top="3cm"/>
</fo:simple-page-master>
</fo:layout-master-set>

<fo:page-sequence master-reference="PageMaster">
<fo:flow flow-name="xsl-region-body">
<fo:block font-family="Batang" font-size="18pt" text-align="center">
Hello: XSL-FO to PDF
日本語
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>


*font-family は実行するPCに入っている適当なTTFフォントを指定します。
(はじめはMS明朝でテストしていたのですが、なぜかMS明朝はうまく乗らないようです、他のTTFフォントを使いましょう。)

・FopFactoryを定義します。
通常は new FopFactoryでいいんですが、せっかくなのでGrailsっぽくSpringBeanとして登録しちゃいます。
conf/spring/resources.groovy を以下のように書き換えます。

import org.apache.fop.apps.FopFactory

beans = {
def fopFactory=fopFactory(FopFactory){
}
}


これでコントローラーやサービスに def fopFactory とするだけで注入されます :)

・レンダリングを実行します
とりあえずコントローラーにでも書いちゃいましょう



def fop={
fopFactory.setUserConfig(new File("fop/fop.xconf"))
OutputStream os = new BufferedOutputStream(new FileOutputStream(new File("fop/fop.pdf")))

try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, os)

TransformerFactory factory = TransformerFactory.newInstance()
Transformer transformer = factory.newTransformer()

Source src = new StreamSource(new File("fop/fop.fo"))
Result res = new SAXResult(fop.getDefaultHandler())

transformer.transform(src, res)
} finally {
os.close()
}

render "ok"
}





素晴らしい!
速度も十分です。
グラフを出したりはまた別の仕組みが必要になってしまうのですが、組版的な細かい調整(長体かけたり、外字使ったり、レイアウト組とか・・・)が出来たり、MarkUpBuilder使ってプログラム的に組んでしまえばデータにあわせて微妙に形をかえるような帳票も出来ちゃいますね!

2009年4月28日火曜日

Grailsで帳票!JasperReport 出力編

めずらしく引き続きJasperReportです。
今回は jasper ファイルから pdf を出力します。

ざっくりコードから!

def report="sample.jasper"
def ds=new JRXmlDataSource("http://localhost:8080/jasper/book/xmllist","/list/book")
def print = JasperFillManager.fillReport(report,[:], ds)
def pdf=new File("test.pdf")
JasperExportManager.exportReportToPdfFile(print,pdf.getAbsolutePath())


reportに帳票ファイルのパスを指定(File型は使えないので注意)

今回はXMLを読み込むのでデータソースにJRXmlDataSourceを作成、前回アクションでxmlを生成するようにしたので、そのURIと、データの基準となるxpathを指定

JasperFillManager.fillReport でレポートファイルと、帳票パラメーター(今回はなしなので空のマップ)、データソースを渡して JasperPrint を作成します。

JasperExportManager.exportReportToPdfFile で出力先のファイルを指定して実行

これでPDFが出力されます。
小さな帳票だったら爆速です!(BIRTと比べて)
ブラウザに表示したい場合は JasperExportManager.exportReportToPdf でPDFのbyte配列がかえるので、これをストリームに返してやればOKです(contentTypeとかはちゃんとセットしてね)

Grailsで帳票!JasperReport 帳票準備編

GrailsでJasperReportの帳票を出力する方法
長いので帳票準備編と出力編に分けます |-`)
XMLを使って出す方法です。
レポートからDB経由して直接引っ張り込む方法もありますが、帳票にあまりロジック的なものをいれたくないので・・・

・Jasperのライブラリをプロジェクトに追加する
公式サイトからjasperreports-3.5.0.jarをダウンロードしてきてプロジェクトの lib フォルダへ突っ込む
PDF出力にiTextを使っているので、iTextと、日本語出力用にiTextAsian.jarとiTextAsianCmaps.jarを入れます。

・DomainをXMLで出力出来るようにする
以下のような感じでxmlを返すアクションを作りましょう。
as XMLは import grails.converters.XML をしてやる必要があります。


def xmllist = {
render(text:Book.list() as XML,contentType:"text/xml",encoding:"UTF-8")
}


・XMLのサンプルデータを取得し、iReportへデータソースの定義をする
上記のアクションにアクセスするとブラウザにXMLが表示されます。(またはダウンロード)
このXMLを保存し、iReportから新規データソースを作成で、XML file datasourceを選択します。



適当な名称と、XMLを指定、Create a datasource using this expressionを選択して xpath を指定します。



・レポートへフィールドをセットする
Field項目の追加で、Descriptionにフィールド名(XMLのノード名)を入れます
追加されたフィールドをレポートへドラッグします
(値が日本語の場合はフォントを日本語フォントに変更します)



Preview を選択するとXMLから読み込まれた値が表示されます。
Previewした時点でテンプレートがコンパイルされ、同名の.jasperファイルが作成されます。
(iReport3.5ではコンパイルの方法がPreviewしか見つかりませんでした・・・)

ここでは日本語がサクっと出るのですが、このままだとPDFにした時に日本語が表示されません。
レポートのXMLを見ると(DesignerとPreviewの間にあるXML)fontタグがあるのですが、こいつにPDF出力用の設定をしてやる必要があります。
(iReport3.5ではここはGUIでは編集出来ないっぽいです)

以下平成角ゴの例です。

<font fontName="Hiragino Kaku Gothic Pro" pdfFontName="HeiseiKakuGo-W5" pdfEncoding="UniJIS-UCS2-H" isPdfEmbedded="true"/>


これで帳票の準備は完了です。
次回はこのjasperファイルを使ってプログラムから帳票を出力します

2009年4月27日月曜日

Grails 1.1 でやってはいけない事(warするとエラーな件について)

とあるGrails1.1のプロジェクトでwarしてTomcatにのっけたら動かないとの事で、、、その時点での1.1.1のSNAPSHOTでやってみたら動いたという情報を元に原因を探してみる事に

結論からいくと、saxonというXSLTプロセッサのライブラリがあると起動に失敗するっぽい
起動時に applicationContext.xml の定義を読む込み所で失敗しているので、ここで使うxmlのparserがsaxonのライブラリと衝突を起こしているっぽい感じ

過去の 1.0.3 とか、1.1.1-SNAPSHOTで動く所を見るとソース上の凡ミスっぽい感じもするけど・・・
(最新の1.1.1-SNAPSHOTにアップデートしたら今度はrun-appも出来なくなった、、、本当に近日リリースされるのだろうか |-`;) )

2009.4.28 追記
最新版はSubVersionではなく、Gitで管理されているもよう、SVNのリポジトリは信頼しちゃダメ!
多分コレ

特に理由がなければ、こちらの方法をを使った方が使いやすいし良いと思います :)

2009年4月21日火曜日

Grails+HiberObjectsでJPAなモデリング

HiberObjectsというEclipseのPluginでHibernate+JPAをGUIモデリングで作れるのですが、これがGrailsに対応していると言う事で使ってみました。

公式サイトはコチラ

最新のEclipseをダウンロードしてきてpluginをセット、Grailsは1.1を使いました。
公式の説明にしたがってHiberObjectsを有効にしていきます、公式のは少し古いみたいでオプションが一部違いましたが、
特に気にするような項目もなかったのでそのまま続行。

公式には Deselect Add Hibernate libraries とありますが、後でHibernate関係でライブラリが見つからないよとエラーが出るのでチェックを入れておきました。
(1.1からはHibernateが完全なPluginとなり、GRAILS_HOMEのlibフォルダにHibernate系のライブラリが入らなくなった為)

設定画面はこんな感じです。




HiberObjectsを有効にしたら、クラスダイアグラムを作ってUMLを描いていくとJavaコードと、hibernate.cfg.xml が生成されます。


あとは generate-all なり、scaffold=true なりして run-app すると普通に CRUD が出来ま、、、、せんでした |-`)
Create,Read,Deleteとリレーション系はちゃんと実装されてるんですが、Editでエラーになります。
ソース見たら自動生成されるファイルに version がありませんでした(´・ω・`)
(クラスに手動で Long version フィールドを追加してやれば CRUD できました)

他にもクラスダイアグラムで削除したクラスやインターフェースが生成され続けるとか、まだまだ微妙な所もあります・・・
Groovyで普通のドメインみたいに作ってくれてUMLが描けるのかと思ってwktkしてたのでちょっと残念、でもGrailsに対応しようとしてくれる辺りが素敵です、今後に期待!

2009年4月20日月曜日

TextmateでGrailsを開発する5つのステップ

GrailsのIDEでは現在以下があります。

・Eclipse
いわずがなとも。Groovy Pluginを入れておくと便利。
だけどGroovyはダイナミックだからJavaほど恩赦は受けられない。

・NetBeans
Grailsへの対応を結構しっかりやっている。
けどコマンド系(run-app とか create-controller とか)の処理はイマイチな気がする。
なんかタスクがうまく落ちなかったりする。

・IntelliJ
無料お試し期間でしか使った事ない |-`)
一番公式な感じ?
高いのであんまり興味無し

と、いくつかあるのですが、どれも重いんですよねぇ
開発はサクサク動かしたいもんです。

というわけでMacな人にはTextmateをオススメします。
Textmateは有料ですがサクサク動いて色々とカスタマイズする事で凄く便利になります。
Grails向けのおすすめカスタマイズを5つ紹介します。

・日本語表示
textmateはデフォで日本語表示が出来ないので、ココらへんを参考に日本語フォントを入れて表示出来るようにしましょう
はじめはつぶれた日本語に違和感がありますが、慣れるとなんてことないです、むしろ幅が揃って良いという気分でいましょう

・Groovy Grailsバンドル
.gsp 表示のシンタックスハイライトや、便利なスニペット(rt[tab]で render(text:"") とか)がつまってます
ココからダウロードできます

・Groovyバンドル
.groovy 表示のシンタックスハイライトや、次のRun Selected Snippetの為にいれておきましょう
ココからダウンロードできます

・Run Selected Snippet
Groovyバンドルの機能の一つです
選択した部分の Groovy を実行できます
GroovyではJavaのクラスへいくつかの便利な機能が付加されてます、詳しくはGroovy JDKにのってますが、
これらの挙動等をちょっとテストしたい時に最適です

例えばテキストファイルの中身を改行でループして、タブ区切りにした1個目の値をごにょごにょしたいな〜と思った時に、
コントローラーを通してやったりせずに、Groovyファイル上の適当な場所に、その部分のコードだけを書いてちょこちょこ動かして確認すれば良いのです


def infile=new File("test.csv")
infile.splitEachLine("\t") { line ->
println line[0]
}


この出力は通常、ウインドが開いてhtml表示されるのですが、ちょこちょこ動かしたい場合はウインドをいちいち閉じるのがめんどいです
Bundle Editorから Run Selected Snippet を見てみると、 exit_show_html となっている部分が2カ所あります
これが通常の出力になってますので、これを exit_show_tool_tip に変更してやります
すると、 tooltip として結果が表示され、ちょっと動かしてやれば消えるのでサクサク使えます

ただ1画面ぐらい出力がされると tooltip では不便です、でもって exit_show_html の出力は html が解析されてしまうので、htmlを見たい時には不便です
なので新規ドキュメントとして開いてやりましょう
今度は exit_show_html の部分を exit_create_new_document に変えてやればOKです

exit_show_tool_tip で tooltip 表示
exit_create_new_document で 新規ドキュメント表示

大事な事なので2回言っておきます :)
この二つを作っておけば大体のケースには対応出来るでしょう。

・リファレンスリンク

Groovyバンドルには Groovy JDK というGroovyの拡張部分がわかるAPIを開くコマンドが追加されます
Grailsでは Groovy 以外にも色々なフレームワーク、ライブラリが使われていますので、これらもサッと開けると便利です
Groovy JDKのコマンドをコピーして、URLの部分を http://grails.jp/links.html に変えましょう
Grails関連のAPI等がざっくり見れます :)




アジャイルなフレームワークにはアジャイルな開発環境を。
これであなたもGroovy!なGrailsライフをおくれる事間違い無し!

GlassFishとBirtの切ない関係

GlassFIshが謎の停止をするので色々とさぐっていったらBirtで帳票を出した時に止まるっぽい

Birtの負荷かな?と思ってJettyとTomcatでアホのように負荷をかけてみたけどまったくとまる様子がない。
というかGlassFIshでは起動直後でも5セッションで帳票を出すと止まる・・・
4セッションだとほとんど止まらない、なんじゃこりゃ

Birt側の問題かと思って最新版に乗せ変えたりもしてみたけど状況は変わらず
うーん、おとなしくjasperReportにしようかなー、Birtである必要性もないし・・・

なんかわかったら続報を入れます

4/23 追記
GlassFish v3の最新版では正しく動作しました
ただしv3ではメモリ関係がv2より厳しいようです、特に -XX:MaxPermSize の指定は必須です

GlassFIsh v3とTomcat、JettyでOKとなると、v2.1に何か衝突する問題がありそうです
Sunからはv3ではまだCluster等が出来ないので本番環境はv2.1を推奨との事ですが、この状態ではv3を使わざるを得ない感じですね・・・
結局しばらくClusterは上位(Apache等)で処理してやるのが良いかもしれません

2009年4月14日火曜日

Grailsで帳票!JasperReport ざっくり評価編

Javaで帳票といえば長い事BIRTを愛用してきたんだけど、食わず嫌いもよくないと言う事で有名なJasperReportを使ってみた、せっかくなんでGrailsで。

まずJasperReportの仕組み。

jasperReportは jrxml というXMLファイルをコンパイルして jasper ファイルを生成して、そこにパラメーターやらデータソースやらを与えて帳票を出力してくれる

出力形式は XLSやPDF、HTML、CSV等が出せる(XLSはPOI、PDFはiTextを使用)

XMLファイルを作成するには iReport というGUIソフトがある
iReportには Classic 扱いの 3.0 と 現行の 3.5 がある
3.5 はNetBeansベースのアプリ(NetBeans用のPluginもある)でマルチプラットフォームなので良さげな感じだが、
Classicに比べると設定出来る項目が少なかったりする
でもMacな自分には選択肢がないので設定出来ない項目はXMLに直接書く事にする :(

一応メニューもマルチランゲージになっているが、ほとんど英語
とりあえず iReport を立ち上げて適当に帳票作ってみて Preview すると日本語もちゃんと通るっぽい

ざーっくり使ってみた感じ、BIRTとの比較等
レポート的に出来る事、出来ない事の比較はあんまりしてないです、とりあえずJavaで帳票出すって所を視野に入れての感想です

ここが○
・データソースがレポート内部と外部がちゃんと別れている所
XMLをURLから動的に生成していたので、BIRTではデータソースから動的に設定する必要があった
そうするとサンプルデータの準備も面倒だし、動的なURLを解析してXMLをパースしてくれないので、設定に不便だった・・・
iReportではアプリ上に別データソースとしてサンプルファイルをセットしておけばいいのですごくらくちん!
データソースを複数用意しといて切替も簡単、実際にコードから生成する時もデータソースを別であてるだけなので、これは凄くいい!

・ファイルがコンパイル出来る
xmlファイルをコンパイルにしてjasperにしておけば印刷時にコンパイルがいらないのでちょっと早いかも?

・テーブルの部分が別エディタとなっている
BIRTでは同じ帳票上でグリッドとか細かく触らないといけない&重たくて反応が遅れるのでイライラする
でも使いかっては今の所BIRTの方が良い(なれてるだけか)

・プログラムに組み込むのが簡単
BIRTではライブラリも含め色々と仕掛けが必要だったが、JasperReportはいくつかのライブラリいれるだけで後はソース上からさくっと作れた、そのままストリーム返しも出来そうだしいい感じ

・PDF周りの設定がしっかり出来る
PDF上のフォントのエンコード、フォント毎にPDFヘの埋め込みするしない、
PDFのバージョン、セキュリティ関係などなど今なら指定し放題!
BIRTではあるのかもしれないけど、触ってる範囲では出来ないっぽい

ここが×
・幅の%指定がない?
BIRTでは大きさに%指定ができ、ものによって大きくなったり小さくなったりが出来たがjasperReportではないっぽい

・iReportが微妙すぎる
NetBeans版は色々と微妙・・・まだこれからなのかな、Classic版を使ったらもっとハッピーになれるのかしら


次回はBIRTでXMLから帳票を出力しているのがあったので、XMLから帳票を作ってみる編
(ああ、次回ネタが溜まりすぎ・・・)

2009年4月13日月曜日

GrailsのServiceでServletContextを使う

もの凄いピンポイントネタですが。

GrailsのController上ではServletContextが勝手に注入されてます。
Service上では注入されてません、そしてSpringBeanでもないので注入も出来ません。
なんか簡単にとる方法ないのかなーと思ってググったら「コントローラーから渡したらええんちゃうん?」みたいな答えしかなくてしょんぼり。
サービスだけで使いたいのよ、BlazeDSとかWebサービスとかさ。

で、grailsApplicationは注入可能なので、こっからたどって取得します。

def grailsApplication

で grailsApplication を注入して、そこからparentのcontextを取得し(SpringのXmlWebApplicationContext)、そこからServletContextがとれます。

def sc=grailsApplication.getParentContext().getServletContext()

やったね :D