2009-04-17 134 views
16

有什么办法可以完全禁用Java安全管理器?
如何禁用Java安全管理器?

我正在试验db4o的源代码。它使用反射来持久化对象,看起来安全管理器不允许反射来读写私有或受保护的字段。

我的代码:

public static void main(String[] args) throws IOException { 
    System.out.println("start"); 
    new File(DB_FILE_NAME).delete(); 
    ObjectContainer container = Db4o.openFile(DB_FILE_NAME); 
    String ob = new String("test"); 
    container.store(ob); 
    ObjectSet result = container.queryByExample(String.class); 
    System.out.println("retrieved (" + result.size() + "):"); 
    while(result.hasNext()) { 
     System.out.println(result.next()); 
    } 
    container.close(); 
    System.out.println("finish"); 
} 

输出:

 
start 
[db4o 7.4.68.12069 2009-04-18 00:21:30] 
AccessibleObject#setAccessible() is not available. Private fields can not be stored. 
retrieved (0): 
finish 


This thread建议修改java.policy文件,以允许反射,但它似乎并没有为我工作。带参数

我开始JVM
-Djava.security.manager -Djava.security.policy==/home/pablo/.java.policy
如此指定的策略文件将是唯一的政策文件中使用

文件看起来是这样的:

 
grant { 
    permission java.security.AllPermission; 
    permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; 
}; 

我上花了近3个小时这并没有任何想法如何使这项工作。 任何帮助表示赞赏。

+0

您是否尝试过从您自己的代码调用setAccessible或其他特权操作? – 2009-04-17 23:45:21

+0

完整的命令行可能也很有用。 – 2009-04-17 23:46:35

+1

您的虚拟机参数是否正确?你似乎有-Djava.security.policy ==? – 2009-04-18 00:09:52

回答

5

你的java.security.policy命令行选项中是否真的有两个'='符号?这是行不通的。请确保您设置该属性为

-Djava.security.policy=/home/pablo/.java.policy 

要真正禁用SecurityManager,干脆完全撤离关闭java.security.manager系统属性应该是足够的。


更新:当我阅读政策文件,以了解更多有关“==”语法,我注意到,除非政策文件是在当前工作目录,它需要被指定的文件作为URL(包括方案)。您是否尝试过使用“file:”方案为策略路径添加前缀?

我也很困惑,因为(假设你是以“pablo”用户身份运行的),它看起来应该默认从主目录加载策略,所以你根本不需要指定它。另一方面,如果您没有以用户“pablo”的身份运行,那么该文件可能无法读取。

6

你可以尝试添加以下内容到程序的主要():

System.setSecurityManager(null); 

为我工作,当我在安全管理问题“可信” Webstart的应用。不知道它是否适用于您的db4o案例,但可能值得一试。

编辑:我不是建议这是安全管理器问题的一般解决方案。我只是提出它作为帮助调试原始海报问题的一种方法。显然,如果你想从安全经理那里受益,那么你不应该禁用它。

4

我发现这个例子如何make private fields and methods accessible到您的代码。基本上,它提炼到使用字段。setAccessible(真)Method.setAccessible(真)

领域例如:

Field privateStringField = PrivateObject.class. 
      getDeclaredField("privateString"); 

privateStringField.setAccessible(true); 

方法例如:

Method privateStringMethod = PrivateObject.class. 
     getDeclaredMethod("getPrivateString", null); 

privateStringMethod.setAccessible(true); 

你也可以看看使用Groovy与Java代码它(目前)绕过了Java代码的访问级限制。虽然,这个留言板发布似乎暗示了这个'功能'may change in future versions of Groovy

相关问题