3

我有一个 TrirdParty API,其中包含一个 CLass [比如说 A]。它有一个奇怪的静态块,类似于以下内容:

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

    //other stuff
}

我想阻止调用System.exit()被覆盖的SecurityManager. 但是,我想在执行SecurityManager此块之前覆盖,然后static我想恢复原始安全管理器。

我知道如何替换/覆盖/恢复SecurityManager

我的问题是如何确定何时static调用块[基本上是在加载类时],以便在此之前我将使用我自己的SecurityManager来防止System.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 只会尝试执行一次静态初始化。如果失败了,你再试一次,JVM 会简单地抛出ClassNotFoundError(我认为),重复原来的异常作为原因。

使类初始化再次发生的唯一方法是丢弃首先加载有问题的类的类加载器,创建一个新的类加载器,然后重新开始加载。然后你又回到了原来的问题。

底线:如果你真的不能改变代码,你就完蛋了。


即使您可以完成这项工作,这听起来像是您的问题的糟糕解决方案/非解决方案。LinkageError 异常意味着该库未能加载本机库,并且对该库的相应native方法调用将失败并显示Error. 充其量你最终会得到一个库,其中一些位可以工作,而其他位则不能。

您应该专注于为您的平台获取正确的本机库和/或配置 JVM 以便它可以找到它。或者找到一个更好的替代 3rd 方库的替代方案,该库不受侵入式许可证执行废话的阻碍。

于 2011-04-05T23:08:37.767 回答