Javaアプレットでリフレクションを使ったところ、以下のようなエラーメッセージが出ました。


java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.java2d)

該当部分のソースコードは以下です。

if(target.getClass() == Graphics.class ||
target.getClass() == SunGraphics2D.class){

解決に繋がる情報提供を募集します。

回答の条件
  • 1人2回まで
  • 登録:2006/06/01 21:39:54
  • 終了:2006/06/02 12:45:02

ベストアンサー

id:quintia No.3

quintia回答回数562ベストアンサー獲得回数712006/06/02 08:23:33

ポイント45pt

前の回答で書き忘れましたが、

if(target.getClass() == Graphics.class ||
target.getClass() == SunGraphics2D.class){

の SunGraphics2D.class の部分が例外を出している張本人ですよね?

この様に直に書くことでこの部分での ClassLoader が sun.java2d.SunGraphics2D を取得しようとして例外を出しています。


で、この様な記述を取り払えばいいわけですが、このif文だけを見る限り、target が java.awt.Graphics(?) でも sun.java2d.SunGraphics2D でも良いように見ます。

もしそうならば、

if (target instanceof Graphics2D) {
}

で全然構わないんじゃないかと思うのですが。

sun.java2d.SunGraphics2D は java.awt.Graphics2D を親に持ってますし(Graphics じゃなくて Graphics2Dなのは、現時点で java.awt.Graphics2D が無い環境は考慮しなくてもいいのでは? と思ったからですが)。


あるいは、もし、この if の中で、「SunGraphics2D かどうかで挙動を変えている部分がある」というのであればそれは「SunGraphics2D のインスタンスかどうか?」で判定するのではなくて、まさにリフレクションを使って「(SunGraphics2D にはあるはずの)このメソッドがあるかどうか?」を以て判定するべきだと考えます。

それは、SunGraphics2D は API ではなくて"あくまでその実装の1つ"なわけでいつ仕様が変わるかもしれない、という考えに依るものです。


いかがでしょうか?

id:westfish

>instanceof で全然構わないんじゃないかと思うのですが。

instanceofは知りませんでした。これで構わない(むしろ好ましい)と思います。

現在はtargetが何のインスタンスであるかを判定してキャストしているわけですが、リフレクションで呼び出したいメソッドを持っているかどうかを判定してduck typing的に判定するという方法もシチュエーションによっては面白いと思います。

しかし私の認識が正しければSWTのfillOvalとAWTのfillOvalは両方ともvoid(int, int, int, int)というシグネチャでありながら挙動が異なります。SWTかAWTかによって呼び出し元で与える引数を変えてやる必要があるので今回はそのアプローチは難しいと思います。

仕様が変わる可能性は否定できませんが、可能性は低いと考えて構わないと思います。

instanceofに変えてみたところ、無事動きました。ありがとうございました。

2006/06/02 12:43:56

その他の回答(2件)

id:ma-kanoh No.1

ma-kanoh回答回数155ベストアンサー獲得回数42006/06/01 23:59:18

ポイント10pt

http://www.ingrid.org/jajakarta/tomcat/tomcat-3.2.1/doc-ja/uguid...

java.policyのjava.lang.reflect.ReflectPermission

を出来るようにJREに設定すれば、Javaアプレットに設定できます。

まぁ、AllPermissionにしてもいいですが。

問題はJavaアプレットを使用するときのJREがなんであるかが分からないことです。どのJREかわからないとjava.policyファイルがどれであるかわからない。。。

IEで、かつJavaプラグインなのであれば、コントロールパネルを見れば分かりますが、、、

id:quintia No.2

quintia回答回数562ベストアンサー獲得回数712006/06/02 00:14:24

ポイント25pt

どういう状況を以て「解決」と言うのかが判らないので回答もしにくいのですが、とりあえず。

(JREのフォルダ)/lib/security/java.security

ファイル中に、

# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.

という記述があって、これによって、sun. で始まるパッケージに属するクラスへのアクセスが禁じられています。


http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/Security...(java.lang.String)

正確には禁じられているのは「アプレットに記述したコードが走っているスレッド」からのアクセスなわけですが。sun.~ を実際にロードして使えうことが許されるのは、より上層の(という表現はちょっと妙ですが)スレッドだけということでしょう。


最初にも書きましたが、質問に挙げられている if文だけでは「何をどうしたいのか?」が判らないのでここまでにしておきます。

セキュリティを下げてでもこういうことがしたいんだ! とか、こういうことをしたいんだけどセキュリティを下げないでやるにはどうするのか? というような情報を提示していただければと思います。

id:westfish

引数として与えられたObject targetが、実際にはどういうクラスのオブジェクトなのかをリフレクションで判定して、適切なメソッドで描画を行うような関数を作りました。描画対象がSWTであるかAWTであるか意識する必要がないようにしようとの意図です。

アプレットビューワでは動いたのですが、ブラウザから見るとセキュリティチェックに引っかかってしまっているわけです。

不特定多数のユーザーにセキュリティポリシーを変更させるのはあんまり現実的ではないので、セキュリティをゆるめずになるべく少ない工数で「AWTでもSWTでも動くレンダリングメソッド」を作りたいと思います。

2006/06/02 03:40:22
id:quintia No.3

quintia回答回数562ベストアンサー獲得回数712006/06/02 08:23:33ここでベストアンサー

ポイント45pt

前の回答で書き忘れましたが、

if(target.getClass() == Graphics.class ||
target.getClass() == SunGraphics2D.class){

の SunGraphics2D.class の部分が例外を出している張本人ですよね?

この様に直に書くことでこの部分での ClassLoader が sun.java2d.SunGraphics2D を取得しようとして例外を出しています。


で、この様な記述を取り払えばいいわけですが、このif文だけを見る限り、target が java.awt.Graphics(?) でも sun.java2d.SunGraphics2D でも良いように見ます。

もしそうならば、

if (target instanceof Graphics2D) {
}

で全然構わないんじゃないかと思うのですが。

sun.java2d.SunGraphics2D は java.awt.Graphics2D を親に持ってますし(Graphics じゃなくて Graphics2Dなのは、現時点で java.awt.Graphics2D が無い環境は考慮しなくてもいいのでは? と思ったからですが)。


あるいは、もし、この if の中で、「SunGraphics2D かどうかで挙動を変えている部分がある」というのであればそれは「SunGraphics2D のインスタンスかどうか?」で判定するのではなくて、まさにリフレクションを使って「(SunGraphics2D にはあるはずの)このメソッドがあるかどうか?」を以て判定するべきだと考えます。

それは、SunGraphics2D は API ではなくて"あくまでその実装の1つ"なわけでいつ仕様が変わるかもしれない、という考えに依るものです。


いかがでしょうか?

id:westfish

>instanceof で全然構わないんじゃないかと思うのですが。

instanceofは知りませんでした。これで構わない(むしろ好ましい)と思います。

現在はtargetが何のインスタンスであるかを判定してキャストしているわけですが、リフレクションで呼び出したいメソッドを持っているかどうかを判定してduck typing的に判定するという方法もシチュエーションによっては面白いと思います。

しかし私の認識が正しければSWTのfillOvalとAWTのfillOvalは両方ともvoid(int, int, int, int)というシグネチャでありながら挙動が異なります。SWTかAWTかによって呼び出し元で与える引数を変えてやる必要があるので今回はそのアプローチは難しいと思います。

仕様が変わる可能性は否定できませんが、可能性は低いと考えて構わないと思います。

instanceofに変えてみたところ、無事動きました。ありがとうございました。

2006/06/02 12:43:56

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません