如何禁用 Java 安全管理器?

2022-09-02 22:06:56

有没有办法完全禁用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


此线程建议修改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个小时在这个上面,没有任何想法如何使它工作。任何帮助赞赏。


答案 1

你可以尝试将它添加到程序的主()中:

System.setSecurityManager(null);

当我遇到安全管理器问题时,为我为“受信任的”WebStart应用程序工作。不确定它是否适用于您的db4o案例,但可能值得一试。

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


答案 2

您的命令行选项中真的有两个“=”符号吗?这是行不通的。确保将属性设置为java.security.policy

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

要实际禁用 ,只需完全省略系统属性就足够了。SecurityManagerjava.security.manager


更新:当我阅读策略文件的文档以了解有关“==”语法的更多信息时,我注意到除非策略文件位于当前工作目录中,否则需要将其指定为URL(包括方案)。您是否尝试过在策略路径前面加上“file:”方案的前缀?

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