我在这里面临一个难题。
我开发的应用程序之一正在加载 DocumentBuilderFactory 的错误实现JAXP 类。后来推断此行为是由不同团队/公司构建的不同应用程序中的另一个类引起的。上述类在加载时更改了首选的 DocumentBuilderFactory 类,方法是包含一个类似于下面的静态 block :
static
{
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "a new factory");
}
如果按照Javadocs of the DocumentBuilderFactory.newInstance方法,很明显,当调用 newInstance 方法时,上面的代码负责更改返回给所有应用程序的解析器实现。
应用了补丁,纠正了这个问题,但它让我问这个问题 - 如何确定哪个类在运行时执行 System.setProperty 调用?
我们已经生成了一个自定义构建的 OpenJDK,其中包含一个修改过的 System 类,该类负责找出罪魁祸首,原因很简单,因为我们无法访问服务器上部署的所有应用程序的所有源代码。但这是可能的,因为生产环境是完整复制的。因此,这个问题也可以解释为 - 如何在生产环境中确定哪个类在运行时执行 System.setProperty 调用?
最佳答案
System.setProperty由 SecurityManager 检查,如果已安装。
您可以创建自己的 MySecurityManager 并在运行时进行部署。当调用方法 checkPropertyAccess
时,您自己的 SecurityManager 可以记录一些信息,例如当前堆栈跟踪:
public class MySecurityManager extends SecurityManager
{
public MySecurityManager()
{
super();
}
@Override
public void checkPropertyAccess(String key)
{
if ("javax.xml.parsers.DocumentBuilderFactory".equals(key))
{
System.err.println("checkPropertyAccess(String :" + key + "): ");
Thread.currentThread().dumpStack(); // or anything useful for
// logging the context.
new Throwable().printStackTrace(); // whatever, or use it with
// PrintStream/PrintWriter, or some logging framework if configured.
}
super.checkPropertyAccess(key);
}
@Override
public void checkPermission(Permission perm)
{
if (perm instanceof PropertyPermission)
{
PropertyPermission propPerm = (PropertyPermission) perm;
System.err.println("checkPropertyAccess(String:" + propPerm.getName() + "):");
Thread.currentThread().dumpStack(); // or anything useful for
// logging the context.
new Throwable().printStackTrace(); // whatever, or use it with
// PrintStream/PrintWriter, or some logging framework if configured.
}
super.checkPermission(perm);
}
}
关于java - 检测 System.setProperty 方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4206489/