TFJ-298 リフレクションで値が取れない

閲覧: 36 回
最初の未読メッセージにスキップ

shinsuk...@gmail.com

未読、
2010/02/04 19:00:092010/02/04
To: Twitter4J J
はじめまして。菅谷です。

StatusJSONImplなどからリフレクションで値が取れず、
以下のようなものを JIRA にあげさせていただきましたが
これは対応していただくことは可能でしょうか?

http://twitter4j.org/jira/browse/TFJ-298

Twitter4Jを利用しようと考えていますが、適用しようとして
いるプロジェクトに期限がありまして、修正していただいた
ものを利用するか、独自に修正したものを利用するか、
検討しているところなので確認させていただきました。

よろしくお願いいたします。

shinsuke

shinsuk...@gmail.com

未読、
2010/02/04 22:07:222010/02/04
To: Twitter4J J
菅谷です。

コメントはこちらに書くようにとあったのでこちらに書きます。

StatusJSONImplなどは将来の変更に対応するために
直接クライアントが参照しないというのはわかるのですが
リフレクションで取れないのも不便なため、JIRAにあげさせて
いただきました。それらの実装クラスを直接参照することは
ありませんが、Seasar2 での話はただの一例で、本件は
リフレクションを使ったときに起きる問題かと考えています。

Twitter4J の方針として、それらを直接参照させないのを
重視するのであればあきらめて、Statusインターフェースの
ラッパークラスとか作って回避することとか考えます。

よろしくお願いいたします。

shinsuke

On 2月5日, 午前9:00, "shinsuke.sug...@gmail.com"

Yusuke Yamamoto

未読、
2010/02/04 22:31:512010/02/04
To: twitt...@googlegroups.com
菅谷さん こんにちは。

インターフェースをpublicにしてクライントに見せ、実装クラスは隠蔽して
将来の変更を容易にするという設計は一般的だと思います。

Seasar2に明るくないのですが、そういった設計のライブラリを扱う場合は
ライブラリ側でクラスを public に修正するのが一般的なのでしょうか?
--
Yusuke Yamamoto
yus...@mac.com

このメールは: [ ] ブログ/Twitterへ転載可能 [x] 私信
Twitter でフォロー : http://twitter.com/yusukey
blogを購読: http://yusuke.homeip.net/diary/

> --
> Twitter4J の最新情報をフォロー: http://twitter.com/t4j_news
> 現在開発中のバージョン: 2.1.1
> http://twitter4j.org/jira/secure/IssueNavigator.jspa?requestId=10030
> バグトラッキング: http://twitter4j.org/jira/browse/TFJ
>
> このメールは次の Google グループの参加者に送られています: Twitter4J J
> このグループにメールで投稿: twitt...@googlegroups.com
> このグループから退会する: twitter4j-j...@googlegroups.com
> その他のオプションについては、次の URL からグループにアクセスしてくださ
> い。 http://groups.google.com/group/twitter4j-j?hl=ja

shinsuk...@gmail.com

未読、
2010/02/05 1:01:552010/02/05
To: Twitter4J J
山本さん

こんにちは、菅谷です。

設計思想は人それぞれありますので、
私の思うこととして書かせていただきます(^^;

> インターフェースをpublicにしてクライントに見せ、実装クラスは隠蔽して
> 将来の変更を容易にするという設計は一般的だと思います。

そのように、ライブラリとして将来の変更にも変更しやすく
するためにそうするのも一つの設計方針だと思います。
(ライブラリを作る側はこれの方が楽かと思います)

Seasar2 のように実際に開発するのに便利かつ必要な
ものを柔軟に対応していくのも一つの方針かと思います。
(利用する側はこっちの方がうれしいと思います)

> Seasar2に明るくないのですが、そういった設計のライブラリを扱う場合は
> ライブラリ側でクラスを public に修正するのが一般的なのでしょうか?

そうするのが一般的かどうかは難しいところですが、
世の中にはフレームワークやライブラリは無数にあるので
Seasar2 に限らず、同じ問題に遭遇していくともあるかと
思います。そのときに、public にして助けてあげるのか、
自身の将来への変更をやりやすくするのか、などなど
何を重視するかな気がします。

また、(ふと思いましたが) public にする以外にも
解決方法はあるかもしれません。たとえば、
StatusJSONImpl を public にしないでもそれを
代理する StatusWrapper みたいな public な
ラッパークラスで返してあげたりすれば、この
リフレクション問題は回避できるような気もしました。

shinsuke

On 2月5日, 午後12:31, Yusuke Yamamoto <yus...@mac.com> wrote:
> 菅谷さん こんにちは。
>
> インターフェースをpublicにしてクライントに見せ、実装クラスは隠蔽して
> 将来の変更を容易にするという設計は一般的だと思います。
>
> Seasar2に明るくないのですが、そういった設計のライブラリを扱う場合は
> ライブラリ側でクラスを public に修正するのが一般的なのでしょうか?
> --
> Yusuke Yamamoto
> yus...@mac.com
>
> このメールは: [ ] ブログ/Twitterへ転載可能 [x] 私信
> Twitter でフォロー :http://twitter.com/yusukey
> blogを購読:http://yusuke.homeip.net/diary/
>

Kazuhiro Kazama

未読、
2010/02/05 1:17:392010/02/05
To: twitt...@googlegroups.com
菅谷さん,

On 2010/02/05, at 15:01, shinsuk...@gmail.com wrote:
> また、(ふと思いましたが) public にする以外にも
> 解決方法はあるかもしれません。たとえば、
> StatusJSONImpl を public にしないでもそれを
> 代理する StatusWrapper みたいな public な
> ラッパークラスで返してあげたりすれば、この
> リフレクション問題は回避できるような気もしました。


Seasar2なら,クラスローダがらみの問題ということはないでしょうか?

http://www.redhat.com/docs/ja-JP/Server_Configuration_Guide/4.3.1/html/Class_Loading_and_Types_in_Java-IllegalAccessException___Doing_what_you_should_not.html
---
風間 一洋 (kaz...@ingrid.org)

shinsuk...@gmail.com

未読、
2010/02/05 1:40:172010/02/05
To: Twitter4J J
風間さん

菅谷です。情報をありがとうございます。
S2 なくても再現するので、そこは大丈夫だと思います。
たとえば、以下のような感じでもおきます。

Twitter twitter = new TwitterFactory().getInstance(username,
password);
List<Status> statusList = twitter.getFriendsTimeline();
Status status0 = statusList.get(0);
// Status status0 = new StatusWrapper(statusList.get(0));
// ↑こんな感じで内部でラップしてもらえると回避できるかと…
Method method = status0.getClass().getMethod("getId", null);

shinsuke


On 2月5日, 午後3:17, Kazuhiro Kazama <kaz...@ingrid.org> wrote:
> 菅谷さん,
>

> On 2010/02/05, at 15:01, shinsuke.sug...@gmail.com wrote:
>
> > また、(ふと思いましたが) public にする以外にも
> > 解決方法はあるかもしれません。たとえば、
> > StatusJSONImpl を public にしないでもそれを
> > 代理する StatusWrapper みたいな public な
> > ラッパークラスで返してあげたりすれば、この
> > リフレクション問題は回避できるような気もしました。
>
> Seasar2なら,クラスローダがらみの問題ということはないでしょうか?
>

> http://www.redhat.com/docs/ja-JP/Server_Configuration_Guide/4.3.1/htm...
> ---
> 風間 一洋 (kaz...@ingrid.org)

Kazuhiro Kazama

未読、
2010/02/05 3:05:042010/02/05
To: twitt...@googlegroups.com
菅谷さん,

On 2010/02/05, at 15:40, shinsuk...@gmail.com wrote:
> 菅谷です。情報をありがとうございます。
> S2 なくても再現するので、そこは大丈夫だと思います。
> たとえば、以下のような感じでもおきます。
>
> Twitter twitter = new TwitterFactory().getInstance(username,
> password);
> List<Status> statusList = twitter.getFriendsTimeline();
> Status status0 = statusList.get(0);
> // Status status0 = new StatusWrapper(statusList.get(0));
> // ↑こんな感じで内部でラップしてもらえると回避できるかと…
> Method method = status0.getClass().getMethod("getId", null);


この例では,Mac OS XとWindows用のJava 1.6で
はエラーにならないようでした.

どのようなJava VMを使われていますか?
---
風間 一洋 (kaz...@ingrid.org)

shinsuk...@gmail.com

未読、
2010/02/05 3:40:262010/02/05
To: Twitter4J J
風間さん

試していただきありがとうございます。
普通の Sun の JVM で、Windows XP で

> java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)

とtwitter4j-core-2.1.0.jarを使っています。
以下のように怒られています。

Exception in thread "main" java.lang.IllegalAccessException: Class
com.test.App can not access a member of class twitter4j.StatusJSONImpl
with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.reflect.Method.invoke(Method.java:588)
at com.test.App.run2(App.java:47)
at com.test.App.main(App.java:20)

shinsuke


On 2月5日, 午後5:05, Kazuhiro Kazama <kaz...@ingrid.org> wrote:
> 菅谷さん,
>

Kazuhiro Kazama

未読、
2010/02/05 4:03:072010/02/05
To: twitt...@googlegroups.com
On 2010/02/05, at 17:40, shinsuk...@gmail.com wrote:
> 試していただきありがとうございます。
> 普通の Sun の JVM で、Windows XP で
>
>> java -version
> java version "1.6.0_17"
> Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
> Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)
>
> とtwitter4j-core-2.1.0.jarを使っています。


Windowsの方はまったく同じ環境ですが,こちらではWindowsでも
Mac OS Xでも例外が投げられません.

なぜだ…?
---
風間 一洋 (kaz...@ingrid.org)

package org.ingrid.twitter;

import java.lang.reflect.Method;
import java.util.List;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;

public class TwitterAPITest {
public static void main(String[] args) throws Exception {
Twitter twitter = new TwitterFactory().getInstance(args[0], args[1]);

shinsuk...@gmail.com

未読、
2010/02/05 4:35:502010/02/05
To: Twitter4J J
菅谷です。

申し訳ありません。
最後の重要な一行が抜けておりました…。

Twitter twitter = new TwitterFactory().getInstance(args[0], args[1]);
List<Status> statusList = twitter.getFriendsTimeline();
Status status0 = statusList.get(0);
// Status status0 = new StatusWrapper(statusList.get(0));
// ↑こんな感じで内部でラップしてもらえると回避できるかと…
Method method = status0.getClass().getMethod("getId", null);

Object object = method.invoke(status0, null);
// ↑これで発生してます(すいません、これが抜けました)

#問題の行を書き忘れるとは疲れているのかもしれません…
#お手数をおかけして申し訳ありません。

shinsuke


On 2月5日, 午後6:03, Kazuhiro Kazama <kaz...@ingrid.org> wrote:

Kazuhiro Kazama

未読、
2010/02/05 6:04:582010/02/05
To: twitt...@googlegroups.com
On 2010/02/05, at 18:35, shinsuk...@gmail.com wrote:
> 申し訳ありません。
> 最後の重要な一行が抜けておりました…。

やっぱり…(笑)

それでバグデータベースを探したら,同じバグがありました.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4396435

この評価では,コードの方を次のように書き換えろと指摘されています.

Method method = status0.getClass().getMethod("getId", null); // ×

Method method = Status.class.getMethod("getId", null); // ○

だから,理想的には,Seasar2のプロジェクトに,このような
呼び出しもできるように機能拡張してもらうように要求するのがよ
いのではないでしょうか?例えば,こんな感じ?

BeanMap map = Beans.createAndCopy(BeanMap.class, status,
Status.class).execute();

あと,バグデータベースをつらつらと見ていると,この辺の直接呼
び出しとリフレクションの挙動のミスマッチの問題は相当あるよう
で,すべてを強引に解決する伝家の宝刀として
setAccessible(true)がありますが,これは強引すぎますね(笑)
---
風間 一洋 (kaz...@ingrid.org)

shinsuk...@gmail.com

未読、
2010/02/05 8:03:482010/02/05
To: Twitter4J J
風間さん

情報をありがとうございます。
勉強になりました。個人的にはどこの方向で対応するに
しても、うーんという感じではありますが時間もないので
持ち帰って考えて対応することにします。ありがとう
ございました!

shinsuke

On 2月5日, 午後8:04, Kazuhiro Kazama <kaz...@ingrid.org> wrote:

Yusuke Yamamoto

未読、
2010/02/10 22:53:322010/02/10
To: twitt...@googlegroups.com
山本です。

このスレッド、追い切れていないのですが
・Sun JVM のバグに起因する問題
・Seasar 側で回避策を実装済み
・Twitter4J サイドで現在の所早急な対応(回避策)の実施は不要
ということで合っているでしょうか?
--
Yusuke Yamamoto
yus...@mac.com

このメールは: [x] ブログ/Twitterへ転載可能 [ ] 私信


Twitter でフォロー : http://twitter.com/yusukey
blogを購読: http://yusuke.homeip.net/diary/

shinsuk...@gmail.com

未読、
2010/02/11 19:01:232010/02/11
To: Twitter4J J
菅谷です。

JVM のバグというより仕様という感じだと
思いますが(不便な感じの仕様ですが…)、
それらで合っていると思います。よろしく
お願いいたします。

shinsuke


On 2月11日, 午後12:53, Yusuke Yamamoto <yus...@mac.com> wrote:
> 山本です。
>
> このスレッド、追い切れていないのですが
> ・Sun JVM のバグに起因する問題
> ・Seasar 側で回避策を実装済み
> ・Twitter4J サイドで現在の所早急な対応(回避策)の実施は不要
> ということで合っているでしょうか?
> --
> Yusuke Yamamoto
> yus...@mac.com
>
> このメールは: [x] ブログ/Twitterへ転載可能 [ ] 私信
> Twitter でフォロー :http://twitter.com/yusukey
> blogを購読:http://yusuke.homeip.net/diary/
>

Yusuke Yamamoto

未読、
2010/02/11 19:26:212010/02/11
To: twitt...@googlegroups.com
承知いたしました。クローズしたしました。

引き続き Seasar との組み合わせで何か問題が発生いたしましたら
お気軽にお知らせいただければ幸いです。
--
Yusuke Yamamoto
yus...@mac.com

このメールは: [ ] ブログ/Twitterへ転載可能 [x] 私信


Twitter でフォロー : http://twitter.com/yusukey
blogを購読: http://yusuke.homeip.net/diary/

Kazuhiro Kazama

未読、
2010/02/11 20:25:432010/02/11
To: twitt...@googlegroups.com
どうもごくろうさまです.

On 2010/02/11, at 12:53, Yusuke Yamamoto wrote:
> このスレッド、追い切れていないのですが
> ・Sun JVM のバグに起因する問題
> ・Seasar 側で回避策を実装済み
> ・Twitter4J サイドで現在の所早急な対応(回避
> 策)の実施は不要
> ということで合っているでしょうか?


簡単に説明します.

・オブジェクトAにリフレクションAPIを使ってアクセ
スする場合に,どのクラスorインタフェースでアクセスすれ
ばよいのかは自明ではないので,リフレクションAPIの呼び出
し側で指定する必要があります.

・Java言語のリフレクションの仕様では,このような場合も
考慮されています.Java言語の仕様の問題 or JVMのバ
グではありません.

・今回のような実装は,例えばNIO APIでも多用されているよ
うに,特殊というほどのケースではありません.

・今回の問題は,Seasar側の呼び出しメソッドに「オブジェ
クトのクラス=呼び出したいクラスorインタフェース」とい
う制約があったからです.私は使っていないので,これを回避する
メソッドが用意されているかはわかりません.

・この問題は他の実装でも起こりえるので,Seasar側のメ
ソッドの利便性を高めるために,もし対応していなければ修正する
(呼び出したいクラスorインタフェースの引数を追加したメ
ソッドを用意する)のが理想的です.

・ただし,Twitter4Jで扱う基本的なデータに対して,オブ
ジェクトの直列化などの他の面も総合的に考慮して,将来的により
シンプルなデータ型にするという選択肢はあるとは思います.

こんなところではないでしょうか?
---
風間 一洋 (kaz...@ingrid.org)


全員に返信
投稿者に返信
転送
新着メール 0 件