sola's note -20ページ目

sola's note

日ごろのメモを書いていきます。何か新しいものを作るために。

java.lang.NoClassDefFoundError: twitter4j/TwitterException
(タイトルに載りきらなかったので一応)

ハマりかけた

JavaアプリケーションとしてTwitter4jを用いたアプリが実行出来るのに
GAEのWebアプリケーションとして実行しようとすると

java.lang.NoClassDefFoundError: twitter4j/TwitterException

…(省略)…

Caused by: java.lang.ClassNotFoundException: twitter4j.TwitterException
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)

…(省略)…

at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

…(省略)…

が発生する。
たまたま実行元がServletだったので
Servletのパスが悪いのか
クラスローダに問題があるのか



超意味わかんねぇ…

という状態。
でも、そもそもJavaアプリケーションとして実行出来るものが、
Servletから呼び出す事が出来ないのはおかしいだろう…と思って、
実行形式を気にして調べてみたら

陽昇れども地の底に光届かず

さんのページの

03. Twitter4Jの追加

を発見!
どうやらビルドパス指定するJarファイルは
warフォルダ配下にないといけない模様。(リンク参照

■以下引用■
実行可能のJARファイルであれば何処に配置されたライブラリであろうともエクスポート時に必須ライブラリがコピーなり抽出されますが、
GAEプラグインのデプロイの場合、warフォルダ以下のファイルのみを対象としているらしく、この中にコピーした上でビルドパス指定しなければ
ならないようです。
■引用終わり■

わかんないよねぇ…w
遂にGAEとTwitterAPIのコラボ

Twitterを扱うには色々方法があるみたいだけど

今回見つけたのはこれ

Twitter4j

多分TwitterAPIを初めてやろう(組もう)と思うと、
壁を感じる部分があると思うけど、

これは異常に楽。

どうやってやるんだか良く分からない状態でも
Twitter4jをライブラリに入れて(パス通して)
ここのページ
4.Tweetの検索…
を普通のクラスファイルに記述して、
mainメソッドから呼び出してみるとわかるはず。

この手ごろさはビックリした。

もうJarファイルをライブラリに入れる方が困難なんじゃないか
って思うくらい楽です。
(Jarファイルは普通にビルドパス通せば良いだけなので特別難しい作業ではなく、
APIの使用がそれくらい楽ということです。)

是非使ってみると良さそうです。
GAE(Google App Engine/J)で検索処理を行う時は
PersistenceManagerという良く分からないマネージャーでQueryオブジェクトを生成して検索を行う。

この時生成されるQueryのオブジェクトにはFilterという条件指定をする事が出来るんだけど、
複数の条件を指定すると

何故か上手くいかない。

例えば
条件が一つの場合、

Query query = pm.newQuery(Hoge.class);
query.setFilter("hoge == 'hoge'");

とやる。
条件を二つにする時に
Listでaddする感覚で

Query query = pm.newQuery(Hoge.class);
query.setFilter("hoge == 'hoge'");
query.setFilter("fuga == 'fuga'");

とやったら、
「hoge==hoge」が

 全 然 機 能 し な い

ちなみにANDを追記して、

Query query = pm.newQuery(Hoge.class);
query.setFilter("hoge == 'hoge' &&");
query.setFilter("fuga == 'fuga'");

でもダメ。
デバックしてみたら、発行されているクエリのwhere以降が

where fuga == fuga

で終わってる
これ(Filter)はもしかしたら1つで固定なのかと思って

Query query = pm.newQuery(Hoge.class);
query.setFilter("hoge == 'hoge' && fuga == 'fuga'");

とか書いてみたら
あっさりいけた。

ちなみに不等式を使った複数プロパティの条件付検索は、
仕様的に無理だそうです。

以下参考。
GAEドキュメント
☆以下引用☆
不等式フィルタが使用できるのは 1 つのプロパティに限られる

クエリが不等式フィルタ(<、<=、>=、>)を使用できるのは、すべてのフィルタにわたって 1 つのプロパティに限られます。
☆引用終わり☆

つまり今回の場合

Query query = pm.newQuery(Hoge.class);
query.setFilter("hoge >= 'hoge' && fuga <= 'fuga'");

は出来ないと思われる。