(署名されていない) アプレット内でカスタム クラスを生成およびロードできるようにしたいと考えています。それらを生成することはできますが、それらをロードすることを望まないように見えるアプレット SecurityManager と戦っています。
これが視覚的な概要です。ご覧のとおり、私はフェーズ 2 で立ち往生しています。
私が最初に意図したのは、カスタム クラス ローダーを使用することでした。どうやらこれはアプレットでは許可されていません。ClassLoader コンストラクターは SecurityException をスローします。
次に、別のクラスローダーで ClassLoader.defineClass(String name, byte[] b, int off, int len)を直接呼び出すことを検討しましたが、そのメソッドは保護されています。
リフレクションを介してメソッドにアクセスできるようにしました。私の希望は高くありませんでしたが、試してみましたが、実際にそれも SecurityException をスローしました。
URLClassLoaderは救いを提供するように見えました: セキュリティ例外をスローしない静的ファクトリ作成メソッドがあります。ただし、この手法では、ローダーのサブクラス化や、保護された defineClass メソッドへのアクセスは許可されません。URL オブジェクトの配列のみを受け入れます。
そのため、 URLをサブクラス化して openConnection メソッドをオーバーライドし、クラス バイトをそのように返そうとしましたが、URL クラスは最終的なものです。
次に、オーバーライドされた openConnection メソッドを使用してカスタムURLStreamHandlerを作成し、それを URL のコンストラクターに渡してみました。SecurityManager は、これに別の適合を投げました。
そこで、カスタム ストリーム ハンドラを返すカスタム ファクトリで URL.setStreamHandlerFactory を呼び出してみました。不平を言わなければ、他に何の役に立つのでしょうか。
そこで、javax.management.loading.MLetを作成してみました。それが何のためのものかはわかりませんが、コンストラクターでカスタム URLStreamHandlerFactory を指定できるようにする URLClassLoader のサブクラスであり、セキュリティ例外をスローすることについては言及していませんが、とにかくそうしました。
必死になって、カスタム ProxySelector を使用してProxySelector .setDefault を呼び出してみました。URL を解読して、どうにかしてそれをアプレットに戻すことを望んでいましたが、その権限もありません。
java.system.class.loader
タグを使用してプロパティを設定しようとし<param name="java_arguments" ...>
ましたが、優先されるプロパティの 1 つではないようです。
最後に、これを行うために考えられる唯一の方法は、URLClassLoader.newInstance(URL[]) と組み合わせて使用できる一時 URL を生成するリモート サーバーにクラス バイトを送信することです。それはうまくいくでしょうが、私はその考えが本当に好きではありません。さまざまな ClassLoaders の相互作用により、複雑になる可能性があり、サーバー依存は私がやりたいことに対して実際には実用的ではないようです。 どうやら、SecurityManager は URLClassLoader を作成できるように喜んでいるだけのようですが、それを使用しようとすると自然に動揺します。
エクスペリエンスがシームレスになるように、可能であれば、通常の署名されていないアプレット セキュリティ サンドボックス内からこれを実行したいと考えています。
しかし、ほとんどの場合、私は困惑しています。なぜなら、それが不可能なら意味がないからです。SecurityManager が任意の外部 URL からクラスをロードすることに満足している場合、ローカル変数のバイト配列からクラスをロードすることを気にする必要はありません。 制限はまだ無意味です。コードはまだ内部にあり、サンドボックス化されています。
動的コード生成と、LZMA 圧縮などのカスタム JAR 圧縮の実装の両方に役立ちます。
ヘルプ!