我可以为您翻译成中文:我可以通过配置java.policy文件来拒绝访问jvm类吗?

5
我想在我的jdk6\jre\lib\security\java.policy文件中添加禁止创建一些被appengine列入黑名单的类。例如,当应用程序尝试实例化javax.naming.NamingException时,我希望我的本地jvm抛出异常。

这是可能的吗?

我会尝试在这里解释我的具体问题。Google提供了一个服务(GAE-google app engine),它有一些限制,不能使用某些类。例如,不会实例化javax.naming包中的JNDI类。他们还提供了一个测试服务器,可以用来在我的机器上测试此应用程序,但此服务器允许使用这些类并且可以执行代码。只有在将应用程序上传到Google后,您才会发现使用了被列入黑名单的类。我在想是否可以在开发jvm上执行此类黑名单强制执行。否则,我认为这将很容易,他们可能已经提供了这样的策略文件。


3
使用白名单优于使用黑名单。 - Tom Hawtin - tackline
3个回答

6

您可以编写一个小的加载器应用程序,创建一个new, 自定义类加载器。然后您的应用程序类可以使用此类加载器加载。

在自定义类加载器中,当您的应用程序尝试访问您想要列入黑名单的类时,您可以抛出ClassNotFoundException。

您需要重载load()方法。该方法将负责在黑名单类上抛出异常或者委托给父ClassLoader(如果允许该类)。一个示例实现:

public Class loadClass(String name) throws ClassNotFoundException {
    if(name.equals("javax.lang.ClassIDontLike")){
       throw new ClassNotFoundException("I'm sorry, Dave. I'm afraid I can't do that.");
    }
    return super.loadClass(name, false);
}

(Of course, a real implementation can be way more sophisticated than this)
因为你的应用程序类是通过这个ClassLoader加载的,当你想要时,你只需要将loadClass()调用委托给父ClassLoader,你就可以黑名单任何你需要的类。
我很确定这是Google在他们的服务器上使用的黑名单类的方法。他们在一个特定的ClassLoader中加载每个应用程序。这也类似于Tomcat隔离不同的Web应用程序的方式。

3
我认为 Class.forName() 可能会绕过自定义类加载器并直接进入引导/系统类加载。我认为有命令行参数可以替换甚至是引导类加载器,也许应该在那里查找。 - basszero
1
你是对的,Class.forName()会使用引导/系统类加载器。这在使用Eclipse时是一个常见的烦恼来源。 - Mario Ortegón

1

在测试程序时,您是否更愿意获得编译错误而不是运行时错误?您可以配置IDE或编译器,在实例化不需要的类时警告您。我知道AspectJ具有一些很好的功能:您可以在连接点上定义编译警告/错误,并在例如Eclipse中获得反馈。要在Eclipse中使用此功能,只需安装AspectJ插件并编写适当的方面即可。要在从命令行或脚本编译时获得错误,您实际上必须使用AspectJ编译器,但我怀疑您是否需要这样做。


0

Java文档在此列出了所有可能的策略权限: http://java.sun.com/javase/6/docs/technotes/guides/security/permissions.html

类创建/加载未被提及,因此我认为您无法使用策略来强制执行此操作。

无论如何,为什么要在加载异常类时抛出异常?也许您可以解释一下您的问题,然后有人可能能够提出解决方案。

编辑:

防止加载某些类的一种方法是将它们从JRE安装中删除。大多数系统类都包含在您的JDK/JRE安装中的rt.jar中。您应该能够使用任何ZIP工具对其进行修改。

只需创建一个特殊的JRE安装程序,并修改其rt.jar即可。这是一种丑陋的hack,但对于测试目的而言应该是可以的...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接