代码之家  ›  专栏  ›  技术社区  ›  Vineet Reynolds

检测System.SetProperty方法调用

  •  3
  • Vineet Reynolds  · 技术社区  · 14 年前

    我面临着一个难题。

    我开发的应用程序之一是加载 DocumentBuilderFactory JAXP类。这种行为后来被推断为是由不同的团队/公司构建的不同应用程序中的另一个类所导致的。所述类在加载时通过包含类似于以下类型的静态块更改了首选的DocumentBuilderFactory类:

      static
      {
        System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "a new factory");
      }
    

    如果有人经过 Javadocs of the DocumentBuilderFactory.newInstance 方法,很明显,当调用newInstance方法时,上面的代码负责更改返回到所有应用程序的解析器实现。

    应用了一个补丁,它纠正了这个问题,但它导致我问这个问题。- 如何确定哪个类在运行时执行System.SetProperty调用?

    我们用一个修改过的系统类生成了一个定制的OpenJDK,这个系统类负责确定罪魁祸首,原因很简单,因为我们没有访问服务器上部署的所有应用程序的所有源代码。但这是可能的,因为生产环境是在其实体中复制的。因此,问题也可以解释为- 在生产环境中,如何确定哪个类在运行时执行System.SetProperty调用?

    5 回复  |  直到 13 年前
        1
  •  5
  •   Vineet Reynolds    13 年前

    System.setProperty 由A检查 SecurityManager ,如果安装的话。

    您可以创建自己的mySecurityManager并在运行时部署。当方法 checkPropertyAccess 被称为:

    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);
        }
    }
    
        2
  •  2
  •   jarnbjo    14 年前

    字符串是以类文件格式编码的utf8,由于没有理由假定有问题的调用程序正在使用代码连接属性名,所以我只需将类路径中的所有jar解包到一个目录中,并尝试通过类文件对“javax.xml.parsers.documentbuilderFactory”执行递归grep。您至少可以找到所有包含此字符串的类文件作为文本,希望不会出现很多误报。

    如果不正确实现的类名更容易识别,那么搜索它可能更聪明。

        3
  •  1
  •   zaletniy    14 年前

    只需在调试模式下启动应用程序,使用Eclipse连接到它,设置断点,并查看调用层次结构中的类是什么。 http://www.eclipsezone.com/eclipse/forums/t53459.html

        4
  •  1
  •   Riduidel    14 年前

    我知道2个解决方案

    1. 使用Aspect框架(AspectJ或So)
    2. 修改系统类(将日志添加到setproperty()方法) new Throwable().printStacktrace(); 将报告方法的调用位置。

    现在用选项运行应用程序 -Xbootclasspath/p 把你的版本系统类放在那里。

    -Xbootclasspath/p:<directories and zip/jar files separated by ;> 在引导类路径前预处理

    我更喜欢第二种解决方案,因为它非常简单。

        5
  •  0
  •   Riduidel    14 年前

    似乎是 aspect 框架,不?

    推荐文章
    robyp7  ·  fo:表到html表-xslt
    10 年前