2013年4月29日月曜日

Eclipse のプロジェクトを IntelliJ IDEA に

ちょっと Heroku の話はお休みして。#f1yosou のサイトはとうとう GAE/J の無料分では Stats が計算できなくなり、あえなく Stats を閉鎖する運びとなりました。で、この際裏で進めていたサイト全体のリニューアルを先にしてしまおうかと思ったのです。なぜなら新しいデザインのほうはまだ Stats ができてなくて時間がかかるなと思っていたんですが、現行のほうも Stats が使えないならもう移行してしまってもいいわけですね。

とはいえまだ公開できるレベルではないのでもう少し実装・テストをする必要があります。なのでこの際現状は Eclipse で開発しているのですが、IntelliJ IDEA を使ってみようと思いました。Java 部分はそれほど大差ないかと思うのですが、Velocity とかこれまではほぼ自前/手書きだったのが便利になるのではという期待もこめて。


ソースコードは subversion にチェックインされているので現状 Eclipse にあるコードはすべてチェックインしておきます。そこからチェックアウトする流れで。 IntelliJ IDEA から VCS > Checkout from Version Control > Subversion を選びます。すると右のようなダイアログがでるので、リポジトリの情報を入力して選択します。その後どこに展開するか場所をしていします。


場所を指定すると次は右のようなダイアログが出るので、私は gae というフォルダ以下に gae 関連のプロジェクトを全部まとめておきたいので、真ん中のやつを選びました。これで gae というフォルダ以下に f1yosou というフォルダができて、そのファイルが中にチェックアウトされます。

するとどうでしょう。
お、Web プロジェクトで、GAE とさらに GWT も使ってることを検出してくれました。Configure を・・・

と思ってこのキャプチャをとっていたらこのポップアップは消えてしまいました!w でもしたの Event Log をクリックしたら同じメッセージとリンクがでていました。ナイスw
Configure をクリックするとこんなダイアログがでるので、OK。
すると File > Project Structure を表示して Facets を見ると、
のように定義されています。あとはここに SDK へのパスを入れたりすればよい。

・・・と思ったんですが、いろいろ問題が。そもそも Dev Server が起動しない(ブランクになる)とか。クラスパス関連がごしゃごしゃになってたりとか。そこでいろいろ苦労しながらなんとかできそうな状態に持っていったやり方を以下に書きます。

まずは新規に GAE/J + GWT のプロジェクトを作成します。File > New Project で Java Module を選択して Next。これで JDO を使う場合はその選択も忘れずに。これで空のプロジェクトができます。空ですがいろいろ設定されているのが大事。

Eclipse でプロジェクトを作った場合は恐らく web ディレクトリではなく war になっていると思うので、ここで web ディレクトリを war に Rename します。web の上で右クリック、Refactor > Rename で war にしましょう。この rename がなぜか反映されてないところがあるのでそこを修正します。プロジェクトを右クリックして Open Module Settings を開くと上にあるようなダイアログが開くので、Facets の Web を選んで、Web Resource Directory 名を変更します。

さていよいよもとのコードを移行します。VCS > Checkout from Version Control > Subversion で上記の作業をします。そのときのチェックアウト先を今作ったプロジェクトそのものにします(つまり上書きします)。そして VCS > Enable Version Control で Subversion を選びます。私の場合 jdoconfig.xml と appengine-web.xml、web.xml が青くなりました。つまりチェックインされているものが変更されているということですね。これらの変更を Revert しましょう。右クリックで Subversion > Revert で戻せます。あと不要な index.jsp も消します。

この状態だとライブラリはパスが通ってない状態なので、WEB-INF/lib に何か入れていた場合はこれらを追加しなければいけません。普通の Java のときと同様ですが右クリックして Add as Library で追加します。また Open Module Settings をして Artifacts の WEB-INF/lib のところに追加するのも忘れずに。

この状態で Run/Debug で AppEngine Dev サーバーを起動したところようやく起動できました。・・・できたんですけどブラウザには悲しいページが。

まだだ!くじけるな!

この話は(たぶん)IntelliJ IDEA 云々ではないようです。既に問題になっていたようで。なので解決方法は Run > Edit Configuration から開くダイアログの VM options に-XX:-UseSplitVerifier をつけるだけ。そしてサーバーを再起動すると・・・
やっとキター!(表示が変なのはデータがまだないからです。)

この勢いで GWT の起動構成も確認します。自分のモジュールの .gwt.xml を右クリックして Run/Debug 。VM Options が必要な場合は上と同様に入れます。そして起動、おりゃーっ!
orz

まあいろいろ起きるもんですね・・・。生みの苦しみかこれは。とはいえこれは簡単に直って、また起動構成に戻り、Server を Default から AppEngine Dev に切り替えて起動しなおすだけでした。ふー。

さあ後は deploy だな! Tools > Upload AppEngine Application を選ぶだけ!
java.lang.RuntimeException: The application contains Java 7 classes, but the --use_java7 flag has not been set.
Unable to update app: The application contains Java 7 classes, but the --use_java7 flag has not been set.
いじめか orz
きっと Java6 にすれば治るんでしょう。GAE って確かまだ Java7 は正式サポートじゃなかったような気がするし。いやもう眠いから調べないですけど。切り替え!もう一度 Upload!

で、できた・・・。

これで恐らく開発できる状態にまではたどり着けた、と思うのですが。しばらく使ってみて今後どうするか考えます。ちなみにこのやり方が正しいのかベストなのか等全く見当もつかないので、もし試す場合は自己責任でお願いします。

2013年4月24日水曜日

Heroku を試す(4)~アプリを作成

さていよいよアプリを作ってみましょう。プロジェクトを作成する画面に Create Heroku App from Template なるメニューがあるのでそれを選びます。

次の画面では・・・何を選びますかね。Getting Started には別にサンプルを作るところまで書かれているわけではないので何も指定はないようです。一番シンプルそうなのは・・・ Embedded Jetty-Servlet Application でしょうか。それを選んで適当に名前をつけて進み・・・ませんw

こんどはこんなエラーが。あれー、ちゃんとセットしたはずなんだけどな。
仕方ないので、前のステップに戻って、Create an SSH Key と Adding your ... のところをやってみます。その後もう一度作ろうとすると、今度は「その名前は既にあるぜー」と言われてしまいます。なので
C:\>heroku apps
=== My Apps
sdk0815-sample


C:\>heroku apps:destroy sdk0815-sample

 !    WARNING: Potentially Destructive Action
 !    This command will destroy sdk0815-sample (including all add-ons).
 !    To proceed, type "sdk0815-sample" or re-run this command with --confirm sdk0815-sample

> sdk0815-sample
Destroying sdk0815-sample (including all add-ons)... done
そして再挑戦すると・・・できたー!
って×出てるしw メッセージを見ると
maven-dependency-plugin (goals "copy-dependencies", "unpack") is not supported by m2e. pom.xml /sdk0815-sample line 48 Maven Project Build Lifecycle Mapping Problem
ふむ・・・。m2e は私が勝手に入れてたプラグインであって、別にここでは必須ではないですよね。ということはエラーが出てても大丈夫か?とりあえずこのまま進めーw

今この状態はどうなってるのか気になるので、Window -> Show View -> Other... で My Heroku Applications ビューを開きます。そこに出てきたアプリを右クリックして Open を選ぶと・・・
キター!

2013年4月16日火曜日

Heroku を試す(3)~ Eclipse を使って

ではこちらに従って Eclipse を使ってアプリケーションを作ってみます。
You can build/deploy and manage your Heroku applications right from within Eclipse using the Heroku Eclipse plugin.
とありますのでプラグインがあるんですね。要件は
ということで Eclipse 3.7 以上を用意しましょう。私は 4.2 で行きます。 更新サイトを追加してインストールするだけ。Eclipse を再起動します。

次はプリファレンスに移動して Email と Password を入れて Login を押せば・・・、あれ。

なぜかエラーが出てますね・・・。いろいろ調べてましたが最終的にはエラービューに行ってみたところ、
Secure storage was unable to retrieve the master password. If secure storage was created using a different Windows account, you'll have to switch back to that account. Alternatively, you can use the password recovery, or delete and re-create secure storage.
なるエラーが出ていました。うーむ。そもそもそのファイルがいつ作られたかも定かではないぐらいなので、消して再起動してみました。すると無事 Login を押したら API Key がセットされました。

次にその下にある Load SSH Key をクリックして、その1で作った .pub をロードします。これで準備完了かな?


2013年4月10日水曜日

Heroku を試す(2)~ Java を使う

さて私の専門(?)は Java なので Java のチュートリアルに進みます。ほかの言語のもたくさんありますね。Java はこちら。要件としては
  • Basic Java knowledge, including an installed version of the JVM and Maven 3.
  • Your application must run on the OpenJDK version 6, or 7 (8 is also available in beta).
  • A Heroku user account. Signup is free and instant.
ふむ。とりあえず Java の知識は当たり前として Maven もこの前いじりましたね。ほんの少しで恐縮ですがw OpenJDK で動くものでないといけないと。アカウントはついこの前作りました。というわけで準備はOK。

さて早速・・・と思ったら
If you’re an Eclipse user you can skip these steps and get started inside of an Eclipse workspace. See Getting Started with Heroku & Eclipse.
Eclipse 用のやり方は別にあるんですね。せっかくなので手に入れた IntelliJ IDEA で行こうかと思ってたんですが、まずは勝手知ったる Eclipse で始めてみます。というわけでそちらのページに従って進めるとします。

2013年4月8日月曜日

Heroku を試す(1)~ Getting Started

#f1yosou のサイトにアクセスしたことのある方なら既に感じられてるかもしれませんが、Google App Engine 上で作っているサイトは結構アクセスしたときのレスポンスが悪いですよね。これはしばらくアクセスがないと Idle 状態になるためです。もちろんお金を払えばインスタンスを常時起動しておけるので早くなるわけですが、別にあのサイトで1円も稼いでないわけでそれはちょっと・・・。

というわけで、ほかの PaaS サービスはどうなのか興味がありまして。最近よく耳にする(気がする) Heroku を試してみます。それで備忘録的にここに手順を書いていきます。私は何事もやってみないと身につかないタイプなので、Getting Started を探しましょう。あ、ありました。ここですね。これに従って進めましょう。

まずは Sign Up から。Eメールアドレスを入れるとメールが届くので、そのリンク先でパスワードを設定するだけです。特に名前とか聞かれないんですね。ログインすると比較的素っ気無い感じのページにログインできます。なんかコマンドっぽい(本当にコマンドかも?)ものが出てるところがちょっと玄人っぽくていいかもw

次は Heroku Toolbelt というものをインストールします。これはなんだろう。
Foreman, an easy option for running your apps locally; and Git, the revision control system needed for pushing applications to Heroku.
とありますね。ということはアプリを管理するツールと git が入るんですね。そういや deploy するのに git を使うってありましたので Linux でやってみようかと思ったけど Windows 用の Toolbelt をダウンロードしてしまったのでとりあえず Windows でやってみます。ダウンロードした exe を起動するだけでするっと入ります。

次はログインですか。早速試してみましょう。
C:\>heroku login
Enter your Heroku credentials.
Email: ********@*****.***
Password (typing will be hidden):
Could not find an existing public key.
Would you like to generate one? [Yn] Y
Generating new SSH public key.
 !    Could not generate key: 'ssh-keygen' は、内部コマンドまたは外部コマンド、
 !    操作可能なプログラムまたはバッチ ファイルとして認識されていません。
あれれ失敗しますね。インストーラーのところで ssh も入れるってあったはずですが・・・。うーむ。仕方ない、とりあえず Cygwin のパスを通して進んでみます。
C:\>set PATH=C:\cygwin\bin;%PATH%

C:\>heroku login
Enter your Heroku credentials.
Email: ********@*****.***
Password (typing will be hidden):
Could not find an existing public key.
Would you like to generate one? [Yn] Y
Generating new SSH public key.
Uploading SSH public key C:/Users/*****/.ssh/id_rsa.pub... done
Authentication successful.
できました。既に key があればそれを使うのもできそうですね。

次はいよいよサンプルアプリを作成してみます。

2013年3月22日金曜日

GAE/J + JDO で Single Property Index を作らせない

表題のとおりですがようやくたどり着いたのでメモ。

サイト自体にも書いていますが、#f1yosou Google App Engine/Java (以下 GAE/J)を使っています。もともと3年前(もう3年になりますか・・・)にはじめたときには結構余裕だったのですが、Googleさんの緩やかな締め付けwで無料での利用部分がどんどん制限されてきて、最初のころにはタコなコードを書いていても余裕があったのですが、最近はかなり厳しくなってきています。これまでもそれなりに使用量を抑制しつつなんとかごまかしてきました。

そんな最近の #f1yosou サイトのもっとも厳しい項目は、Datastore Write Operations の項目です。これは文字通り Entity を Datastore に書き込むと消費するやつですね。これが特に #f1yosou タグのついたツイートを解析して結果を書き込む処理を経るとかなり消費されます。処理としては
  • 該当するツイートの保存
  • 同一の予想をしたツイートのカウントを行い、その結果を保存
ということをしていますが、どうも後者の処理がかなりの書き込みを生じているようです。そもそもこの Datastore Write とは Entity を1つ書き込むと1回なのか?というところから調べ始めたところ、以下の記事がよくまとまっておりました。
EntityのPropetryの構成よって、Datastore writeの数は変わる!
なるほど。そもそもプロパティの数によって増えるのもあるんですがそれは実際に値をしまってるので仕方ないとして、各プロパティについて勝手に自動的に作成される Index の書き込みのほうが問題ですね。そもそも使ってないのに昇順・降順で2つ作られてるみたいですし。これを削減できればだいぶ効きそうです。ただし
Single Property Indexを作らないとComposite Indexも作成されない?
という考慮点もあるみたいなのでなんでもかんでも削れるわけではないようです。

と、ここまできて JDO ではどうやって指定するんだろう・・・と思って調べてもなかなかでてきません。いろいろググっていたらようやく Entity#setUnindexedProperty() なるものがでてきました。しかしこれも Low Level API。。。

まあそれでもいいか、と思ってやり方を探っていたらとうとう発見しました。まんまの質問がありましたw なぜこれに最初に行き当たらなかったのか不思議なぐらいそのままです。要するに
@Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
を索引がいらないプロパティにつけるだけです。あら簡単。

早速実験してみます。1回処理すると以下のようになる Entity を用意しました。
 このクラス定義のところにある correct というプロパティに Index を作らないようにします。
 @Persistent
 @Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
 private Boolean correct;
とすると、
のように2減りました。この2というのが昇順と降順で1つずつの結果のようです。
#上では赤丸がついている Entity にのみ処理をしました。

これで削減できるかな?

2013年3月18日月曜日

Eclipse + Maven その2

続きです。これだけでも十分便利なんですが、よくできてんなと思ったところをもう少し。今回想定しているのは前回作ったプロジェクトで Selenium を使ったコードを書いて隠蔽し、それを別のプロジェクトから利用するというシナリオです。

まず sample1 の App クラスを変更しておきます(別に main のままでもできますが、雰囲気を出すために)。そして後述する実験のために一度 sample1 を install しておきます。sample1 の pom.xml を右クリックして、Run As -> Maven install... を実行します。
 sample1 と同じように sample2 プロジェクトも作ります。
で、pom.xml を開き、dependency のところで sample1 を追加します。
すると
のようになります。アイコンでわかるとおりプロジェクト参照になってます。なので普通に sample1 のクラスが使えるので
とやって実行しただけでブラウザが上がってきます。

これだけでも十分便利なんですが、よくできてんなと思ったのはこの先です。さきほどプロジェクト参照になってると書きましたので、sample1 の App のほうを

のように変更して sample2 の Main を実行すると
と Yahoo! が開きます。ここで sample1 を閉じます。
すると先ほどプロジェクト参照になっていたものが最初にインストールしたほうに自動的に変更されます。
なので実行すればちゃんと動作しますが、開くのは Google のほうです。つまり、インストールされていればその依存を書くだけで使えますが、プロジェクトがあればそちらのコード変更を即座に反映した開発が可能ということです。これは便利ですね。