views:

2020

answers:

4

Is there any way to completely disable Java security manager?

I'm experimenting with source code of db4o. It uses reflection to persist objects and it seems that security manager doesn't allow reflection to read and write private or protected fields.

My code:

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

Output:

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 suggests modifying java.policy file to allow reflection but it doesn't seem to work for me.

I'm starting JVM with arguments
-Djava.security.manager -Djava.security.policy==/home/pablo/.java.policy
so specified policy file will be the only policy file used

The file looks like this:

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

I spent last 3 hrs on this and don't have any ideas how to make this work. Any help appreciated.

+1  A: 

Do you really have two '=' signs in your java.security.policy command line option? That won't work. Make sure you are setting the property as

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

To actually disable the SecurityManager, simply leaving off the java.security.manager system property altogether should be enough.


Update: As I was reading the documentation for policy files to learn more about the "==" syntax, I noticed that unless the policy file is in the current working directory, it needs to be specified as a URL (including scheme). Have you tried prefixing the policy path with the "file:" scheme?

I was also puzzled because (assuming you are running as user "pablo"), it looks like that policy should be loaded by default from your home directory, so you shouldn't need to specify it at all. On the other hand, if you are not running as the user "pablo", maybe the file is not readable.

erickson
That doesn't work. Neither does not passing any arguments to JVM.BTW '==' means that specified file will be the only file used. Single '=' means that the file will be used along with standard policy files. At least that's what I've read.
Pawel Piatkowski
A: 

You could try adding this to the main() of your program:

System.setSecurityManager(null);

Worked for me for a "trusted" WebStart application when I was having security manager issues. Not sure if it will work for your db4o case, but it might be worth a try.

EDIT: I'm not suggesting that this is a general solution to security manager problems. I was just proposing it as a way to help debug the original poster's problem. Clearly, if you want to benefit from a security manager then you should not disable it.

hallidave
That's generally not advised as it can be used by malicious code to take down security and gain local user privileges.
Tom Hawtin - tackline
The original poster *is* looking to 'completely disable' the security manager! :-)
Brian Agnew
Doesn't work :/ thanks anyway
Pawel Piatkowski
+1  A: 

I found this example of how to make private fields and methods accessible to your code. Basically, it distills down to the use of Field.setAccessible(true) and Method.setAccessible(true)

Field example:

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

privateStringField.setAccessible(true);

Method example:

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

privateStringMethod.setAccessible(true);

You could also look at using Groovy with your Java code as it (currently) circumvents much of the access level restrictions of Java code. Although, this message board posting seems to suggest this 'feature' may change in future versions of Groovy.

Kevin Williams
By disabling the security manager you get permission to call setAccessible(true). Without disabling the security manager you wouldn't have a prayer.
extraneon
@Kevin: I can call setAccesible for private fields in my own code. And by 'my own code' I mean a class I added to db4o sources.
Pawel Piatkowski
You should be able to call it on your code as long as you are not running it in an an applet or some other environment with a contravening security manager just as (+1) @extraneon suggests. This artima post has a good explanation of Java Security Manager: http://www.artima.com/underthehood/securitymanager.html
Kevin Williams
A: 

Problem solved. Well, sort of. Problem does not occur with db4o 7.8.

Pawel Piatkowski