2009-06-13 60 views
3

我想给我的jdk6\jre\lib\security\java.policy文件添加一个阻止来创建一些被appengine列入黑名单的类。例如,我希望我的本地jvm在应用程序尝试实例化javax.naming.NamingException时抛出异常。我可以通过配置java.policy文件来拒绝对jvm类的访问吗?

有可能吗?

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

+2

将白名单列入黑名单。 – 2010-03-03 02:19:03

回答

6

您可以编写一个小型加载程序应用程序,该应用程序创建一个new, custom classloader。然后可以使用这个类加载器加载你的应用程序类。

在自定义类加载器中,您可以在应用程序试图访问您想要黑名单的类时引发ClassNotFoundException。

您将需要重载load()方法。如果类允许,这个方法将负责在列入黑名单的类上抛出异常或者转到父类加载器。实现示例:

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); 
} 

(当然,真正的实现可能的方式比这更复杂)

因为你的应用程序的类通过这个类加载器加载,而你只委派的loadClass( )在需要时调用父类加载器,您可以将您需要的任何类加入黑名单。

我确定这是Google用来在其服务器中将类黑名单的方法。它们加载特定类加载器中的每个应用程序。这也与Tomcat隔离不同Web应用程序的方式类似。

+1

我觉得Class.forName()可能会绕过一个自定义类加载器,然后直接进入引导/系统类加载。我认为有命令行参数可以替换引导类加载器,也可能要查看它。 – basszero 2009-06-17 14:59:54

0

Java文档列出了所有可能的政策权限的位置:没有提到 http://java.sun.com/javase/6/docs/technotes/guides/security/permissions.html

创建类/加载,所以我相信使用策略,你不能强制这一点。

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

编辑:防止某些类型的负载会从JRE安装中删除他们

的一种方式。大多数系统类都包含在JDK/JRE安装中的rt.jar中。你应该可以用任何ZIP工具修改它。

只需创建JRE的特殊安装,并修改其rt.jar。这是一个丑陋的黑客攻击,但应该可以用于测试目的...

1

在测试程序时,你宁愿得到比运行时错误更多的编译错误吗?您可以配置您的IDE或编译器,以在不需要的类实例化时发出警告。我知道AspectJ有一些很好的功能:您可以在连接点上定义编译警告/错误,并在例如蚀。要在Eclipse中使用它,只需安装AspectJ插件并编写一个合适的方面。要从命令行或脚本编译时得到错误,你实际上必须使用AspectJ编译器,但我怀疑你会需要它。