3

CLass [A としましょう] を含む TrirdParty API があります。次のような奇妙な静的ブロックがあります。

class A
{
    static
    {
        try
        {
            System.loadLibrary("libraryName");
        }
        catch(UnsatisfiedLinkError ue)
        {
            System.exit(0);
        }
    }

    //other stuff
}

System.exit()オーバーライドされたへの呼び出しを防止したいSecurityManagerSecurityManagerただし、このブロックが実行される直前をオーバーライドし、その直後にstatic元のセキュリティ マネージャーを復元したいと考えています。

を置き換える/上書きする/復元する方法を知っていますSecurityManager

static私の問題は、ブロックがいつ呼び出されるか[基本的にクラスがロードされるとき]をどのように決定するSecurityManagerSystem.exit()ですSecurityManager.

静的ブロックが実行されている間のみ、セキュリティ マネージャをオーバーライドすることが重要であることに注意してください。

編集:

ライセンス上の理由から、ソースを変更することはできません。

4

2 に答える 2

1

Javassist などのバイトコード処理ライブラリを使用して、static{} ブロックを必要なものに置き換えることができないのはなぜですか?

于 2011-04-05T22:15:52.053 に答える
0

基本的にお腹いっぱいだと思います。

はい、(少なくとも理論上は)System.exit()セキュリティ マネージャーを介して呼び出しをブロックすることは可能です。しかし、その後どうなりますか?

  1. クラスの静的初期化子が を呼び出そうとしていますSystem.exit()
  2. SecurityManager は、できないと言い、SecurityException をスローします
  3. クラスの静的初期化がキャッチされない例外で失敗する
  4. 最初に (暗黙的に) 初期化しようとしていたクラスの初期化が失敗します。

理論的には、例外をキャッチできます。しかし、JVM は静的な初期化を 1 回しか実行しようとしないため、これではうまくいきません。それが失敗した場合、再試行すると、JVM は単純にスローしClassNotFoundError(私が思うに)、元の例外を原因として繰り返します。

クラスの初期化を再度発生させる唯一の方法は、問題のあるクラスを最初にロードしたクラスローダーを破棄し、新しいクラスを作成して、ロードを再開することですそして、元の問題に戻ります。

結論: 本当にコードを変更できない場合は、詰め込みすぎです。


これを機能させることができたとしても、問題の解決策が不十分/非解決策のように思えます。LinkageError 例外は、ライブラリがネイティブ ライブラリの読み込みに失敗したこと、およびライブラリnativeへの対応するメソッド呼び出しがError. せいぜい、いくつかのビットが機能し、他のビットが機能しないライブラリになってしまうでしょう。

プラットフォームに適したネイティブ ライブラリを取得するか、JVM がそれを見つけられるように構成することに集中する必要があります。または、押し付けがましいライセンス強制のがらくたに邪魔されない、サードパーティのライブラリに代わるより良い代替手段を見つけること。

于 2011-04-05T23:08:37.767 に答える