2009年12月31日
GWTを用いてGoogle Wave Gadgetを開発する
- kenji
- 14:08
- コメント (4)
- カテゴリー:GoogleWave
Google Wave GadgetはGoogle Gadgetの拡張であるため、通常はJavaScriptを用いて開発します。
7. とりあえず動かしてみる
11. 貼り付けたWaveをFirefoxとChromeで見てボタンのカウントアップが共有されていることを確認
しかし、JavaScriptっていまいちよくわからないよ!!とか、JavaScriptで開発するのめんどくさいよ!!と言う方も多いでしょう。
そこでGoogleのWebアプリケーション開発フレームワークのGWT(Google Web Toolkit)を用いてGoogle Wave Gadgetを開発する方法を紹介します。
GWTを使うとJavaScriptを一切使わず、使い慣れたJavaだけでGoogle Wave Gadgetを開発することができます。
JavaのコードはGWTによってJavaScriptにコンパイルされて動作します。
JavaScriptなのでブラウザ上で完結するプログラムも書くことができるし、もちろんサーバとAjaxで通信するプログラムを書くこともできます。
JavaScriptに精通した人よりもJavaに精通した人の方が多いだろうし、GWTを用いて損はありません。
と言うことでGWTを用いてGoogle Wave Gadgetを開発します。
■必要なもの
・Eclipse 3.5とか適当に
・Google Plugin for Eclipse
http://code.google.com/intl/ja/eclipse/docs/download.html
・Google Apps Engineのアカウント
(無くても良いけどDeployが楽)
■作るもの
ボタン押したらカウントアップしていくカウンタ
■開発手順
1. まず開発環境の構築
EclipseにGoogle Plugin for Eclipseをインスコ
2. Web Application Projectの作成
Eclipseのメニュー[File]->[Other]から[Google]->[Web Application Project]を選択します。
適当に設定する。下の画面写真ではGoogle SDKは2.0だけど日本語版の最新の1.7.1でも可です。

3. 必要なライブラリの取得1
GWTからGadgetsを作成するためのライブラリをダウンロードします。
gwt-google-apis
http://code.google.com/p/gwt-google-apis/downloads/list
上記ページからgwt-gadgets-1.0.3.zipをダウンロードします。2009/12/31時点で1.0.3だけど、最新のバージョンがあれば最新の方が良いと思います。
解凍するとgwt-gadgets.jarと言うJarファイルがあるので、それを2で作成したプロジェクトのwar\WEB-INF\libにコピーします。
プロジェクトのプロパティを開き、Java Build PathのLibrariesタブを開きます。
そしてAdd JARsボタンを押下し、先ほどコピーしたgwt-gadgets.jarを選択します。
次に、Google Gadgetsの設定でもgwt-gadgets.jarを使用する設定を行います。
src/PACKAGE/PROJECT-NAME.gwt.xmlファイルを開きます。
(2で示した例ではsrc/jp.rainbowdevil/TestGadget.gwt.xmlを開く)
XMLに次の行を<module>タグ内に追加します。
<inherits name="com.google.gwt.gadgets.Gadgets" />
4. 必要なライブラリの取得2
3でインストールしたのGWTからGoogle Gadgetsを作成するためのライブラリで、Google Wave Gadgets用のAPIは提供されておりません。
たとえばWaveのSharedStateの取得や、SharedStateの更新時のイベントハンドラの機能は持っていないです。
そこでcobogwaveを使用します。
cobogwaveを使用するとJavaからGoogle Wave GadgetsのSharedStateを操作したり、SharedStateの更新を検知ししたりすることができます。
まずdownloadsからJarファイルを取得します。(2009/12/31時点でVersion 1.0.3.3)
war\WEB-INF\libにコピーし、プロジェクトのプロパティを開き、Java Build PathのLibrariesタブからcobogwave-gadget-1.0.3.3.jarをビルドパスに追加します。
次にGoogle Gadgetsの設定でもcobogwaveを使用する設定を行います。
3と同じようにTestGadget.gwt.xmlを開き、次の1行を<module>タグ内に追加します。
<inherits name='org.cobogw.gwt.waveapi.gadget.WaveGadget' />
またentry-pointのclassも変更しておきます。
子のクラス名は5. ガジェットの作成で作成するクラスを指定します。
<entry-point class="jp.rainbowdevil.client.CounterGadget" />
5. ガジェットの作成
適当なパッケージにガジェットのクラスを作成します。
例ではjp.rainbowdevil.clientにCounterGadgetクラスを作成します。
そしてスーパークラスはWaveGadget
次にガジェットの設定をアノテーションを用いて設定します。
ガジェットのタイトルと、作者名と、作者のメールアドレスと、ガジェットの高さを指定しています。
@com.google.gwt.gadgets.client.Gadget.ModulePrefs(title = "CounterGadget", author = "kenji", author_email = "kenjikitamura@gmail.com", height = 200)
よってクラス定義は次にようになります。
@com.google.gwt.gadgets.client.Gadget.ModulePrefs(title = "CounterGadget", author = "kenji", author_email = "kenjikitamura@gmail.com", height = 200)
public class CounterGadget extends WaveGadget
6. 画面の作成
適当に画面を作成します。
HorizontalPanelの上にラベルとボタンを配置。
private Label counterLabel;
private Button countUpButton;
@Override
protected void init(UserPreferences preferences) {
HorizontalPanel hvpanel = new HorizontalPanel();
counterLabel = new Label("0");
countUpButton = new Button("Count Up");
hvpanel.add(counterLabel);
hvpanel.add(countUpButton);
RootPanel.get().add(hvpanel);
}
今回はGoogle Apps Engine上にDeployして動かしてみます。
なぜGoogle Apps Engineかというと、Webサーバを準備する必要が無くコンパイルとアップロードがボタン一つで良いためです。
適当にGAEのアカウントを取得し、Eclipseのツールバーから[Deploy App Engine Project]を選択します。

すると次のダイアログが表示されるので、App Engine project settings...をクリック。

GAEのアプリケーションIDを設定します。

そしてOKボタンを押下、Deploy Project to Google App Engineダイアログに戻り、GoogleアカウントのIDとパスワードを入力しDeployを押下します。
ConsoleにDeployment completed successfullyと表示されればOK!
8. Waveに貼り付け
Deployが完了したのでWaveに貼り付けて画面を確認します。
Waveに貼り付けるためのURLはGAEを使用した場合、次のようになります。
http://[GAEアプリケーションID].appspot.com/[プロジェクト名]/[パッケージ名].[エントリークラス名].gadget.xml
例:
http://gwttest1203.appspot.com/testgadget/jp.ranbowdevil.client.CounterGadget.gadget.xml
貼り付けたらこんな感じ。まだボタンのコードを書いていないので押しても何も起こりません。
9. カウントアップ処理の追加
ボタンに次のhandlerを追加します。
SharedStateから値を取ってきてインクリメントしてSharedStateに設定しているだけ。
countUpButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
int count = Integer.parseInt(getWave().getState().get("VALUE", "0"));
count++;
getWave().getState().submitValue("VALUE", ""+count);
}
});
10. SharedStateの更新時のイベントハンドラの追加
initメソッドの中に次のコードを追加します。
SharedStateが更新された場合、自動でこのイベントハンドラが発火します。
ガジェット初期表示時にも呼ばれるので、とりあえずここに画面描画処理を書いておけばOK
getWave().addStateUpdateEventHandler(new StateUpdateEventHandler() {
@Override
public void onUpdate(StateUpdateEvent event) {
counterLabel.setText(getWave().getState().get("VALUE","0"));
}
});
と言うことで、JavaScriptを一切書かず、Google Wave Gadgetを作成できました。
ちゃんちゃんっ!
2009年12月27日
Google Wave Hackathonで1位!
昨日はGoogle Wave Hackathon in Kyotoに参加してきました。
Google Wave上で動作するアプリを1日で作り上げるというイベントで、朝から6チームで様々なアプリを作り、夕方から発表しました。
俺はToolチームと言うことで、GoogleWave上でマインドマップを描くことができるガジェットを作成しました。

画面はGWTで作り、グラフはHTML5のCanvasを使って描画。
データの永続化は独自形式のテキストフォーマットを作成し、そのテキストをSharedStateに保存するようにして作成しました。
そして見事1位!!
ちなみにアイデアのおもしろさを競うアイデアソンでは2位でした。
Hachathonは相変わらず激しく疲れるイベントだけど、同時に激しく楽しいイベントでもあります。
また近々別のHackathonが行われるので興味がある方は是非。
ちなみにHachathonのコツは、事前にアプリを設計しその設計で思うように作ることができるか技術を検証しておくことだなー。
しっかり調べたつもりでも、当日「うまくいかねー!!どうしよ・・・」と言うことがよく起こるし。
昨日も思っていた通りに動かない事があって焦った焦った。
でも自分が担当した部分では問題なくスムーズに事は進んだおかげで無事に完成!
前日4時までがんばって調査した甲斐があったぜ・・。
と言うことで1位の賞品としてGoogleが出した新しいプログラミング言語GoのTシャツもらってきました。
いわゆる淫獣ですw
とりあえず近頃Google Wave勉強会の講師やHackathonの準備で疲れすぎた。
しばらくゆっくりするかー。
2009年12月20日
Ubuntu9.10+RAID1+KVM+ブリッジ接続
以前のサーバを導入してからぴったり5年たったので、新サーバを導入してみた。
Core i7の2.6G、メモリ6G、HDD1TのRAID1。
5年前に買ったCeleron 2.4G メモリ256G、HDD80GのRAID1とは大違いのスペックだ。
早速Ubuntu9.10を入れて、その上にRAID1を構築してKVMで仮想化し、その上でサーバを動かしてみた。
RAID1の構築はUbuntuのRAID1構成によるインストールをみてサクッと完了。
KVMは結構良い感じ。VMwareよりはやっぱりめんどくさいけど、VMwareはVMwareでいろいろ最新のLinuxだと入れるのめんどくさかったりするからKVMで十分だ。
問題はまだKVMが新しい技術だから情報が少ないことぐらいか。
KVM上のネットワークをブリッジ接続するのがちょっと手間取った。
kvmのブリッジ設定を参考に設定したらちょっと解決。
でもゲストOSから外の世界が見えない・・・。どっか設定ミスってるんだろうか。
VMwareはなれてるから設定の仕方わかるけどKVMはまだよくわからないな。
とりあえず旧サーバの情報は仮想化したサーバの上に引っ越ししよう。
仮想化するとオーバーヘッドは出てしまうけど管理は楽なのでランニングコストは下がるはずだ。
それにしても5年前と比べてスペックあがったなぁ。
あと5年たったらコアが20個ぐらいあってメモリが50GほどあってHDDが100Tぐらいあるんだろうか。
Linuxもメジャーバージョンアップして3が出てるかもしれないな。
とりあえずこのサーバを使い倒すぞ!
2009年12月12日
Google Wave勉強会おわた
ふいー。
Google Wave勉強会で2時間がっつりGoogle Waveについて話してきました。
初めて勉強会の講師をしたけど結構おもしろかったな。
準備は死ぬほど大変だったけど。
スライド120枚はさすがにきつい。
仕事もきつい時期だったので準備で死ねる。
スライドをレビューしていただいた(lambda (x) (氏に激しく感謝。
やっぱりレビューしてもらわないと、自分では気がつくことができない部分とかもあるしなー。
そのまま発表してたら確実にgdgdになってただろう。
お世辞でも「今までの勉強会で一番よかったです」なんて言われたのでテンションあがっちまったぜww
ちょっと前半緊張して早口になってしまったり課題も残るけど、それ以上に良い経験ができたのでよかったよかった。
2009年12月02日
ノンブロッキングモードのsocket
ちょいとメモ。bind
bzero((char *)&_srcAddr, sizeof(_srcAddr));
_srcAddr.sin_port = htons(port);
_srcAddr.sin_family = AF_INET;
_srcAddr.sin_addr.s_addr = INADDR_ANY;
// ソケットの生成(ストリーム型)
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
int sock_option = 1;
setsockopt(serverSocket,SOL_SOCKET,SO_REUSEADDR,&sock_option ,sizeof(sock_option ));
// ソケットのバインド
if( bind(serverSocket, (struct sockaddr *)&_srcAddr, sizeof(_srcAddr)) == -1 ){
LOG4CXX_ERROR( logger , "Socket Bind Error !!");
return false;
}
LOG4CXX_DEBUG( logger , "Socket Bind success.");
accept
ここでノンブロッキングモードの設定
_dstAddrSize = sizeof(_dstAddr); // これ必要
dstSocket = accept( serverSocket , (struct sockaddr *)&_dstAddr, &_dstAddrSize);
// TEST ノンブロッキングモード
u_long val=1;
ioctl(dstSocket, FIONBIO, &val);
LOG4CXX_DEBUG( logger , "accept!! socket=" << dstSocket);
if( errno != EINPROGRESS ){
LOG4CXX_DEBUG( logger , "SOCKET ERROR! " << errno);
}
データ受信
int length = recv( sock , buff , BUFFER_SIZE , 0);
if (errno == EAGAIN){
// 何も無し
}