有没有办法完全禁用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 :(得分:6)
您可以尝试将其添加到程序的main()中:
System.setSecurityManager(null);
当我遇到安全管理器问题时,为我工作了一个“可信”的WebStart应用程序。不确定它是否适用于您的db4o案例,但可能值得一试。
编辑:我并不是说这是安全管理器问题的一般解决方案。我只是提出它作为一种帮助调试原始海报问题的方法。显然,如果您想从安全管理器中受益,那么您不应该禁用它。答案 1 :(得分:5)
你的java.security.policy
命令行选项中确实有两个'='符号吗?那不行。确保将属性设置为
-Djava.security.policy=/home/pablo/.java.policy
要实际停用SecurityManager
,只需完全取消java.security.manager
系统属性即可。
更新:当我阅读政策文件的文档以了解有关“==”语法的更多信息时,我注意到除非策略文件位于当前工作目录中,否则它必须是指定为URL(包括方案)。您是否尝试使用“file:”方案为策略路径添加前缀?
我也感到困惑,因为(假设您以“pablo”用户身份运行),默认情况下应该从您的主目录加载该策略,因此您根本不需要指定它。另一方面,如果您没有以“pablo”用户身份运行,则该文件可能无法读取。
答案 2 :(得分:4)
我找到了如何make private fields and methods accessible代码的示例。基本上,它提炼使用 Field.setAccessible(true)和 Method.setAccessible(true)
字段示例:
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。