GetPropertyAction vs System.getProperty in obtaini

2019-04-19 09:05发布

问题:

I have been using quite a lot of

System.getProperty("property")

in order to obtain environmental information. However, it seems to me that Sun prefers the following :

(String) java.security.AccessController.doPrivileged(
               new sun.security.action.GetPropertyAction("property"));

The strange thing is that this code involves a cast and as a result should be slightly slower than the

System.getProperty

implementation, that only uses a security manager and then instantly fetches the property from the instance variable props. My question is why did Sun chose to use the second method to obtain most environmental variables in their code internally, while

System.getProperty

seems like the faster way to go?

回答1:

Both methods have a different meaning, and thus the right one has to be used depending on what the current code needs to do.

The code System.getProperty("property") says "Give me the value of the property, if the current security context allows me to read it."

The code that uses doPrivileged says "Give me the value of the property, if the current class (where this line of code is in) is allowed to read it."

The difference comes into play, when the protection domain of the current class is different from the currently active security context.

For example, consider a framework which executes the code of a plugin, which is untrusted. So the framework uses a SecurityManager to restrict the actions of the untrusted plugin code. But of course the plugin may call some methods of the framework, and suppose that one of these methods needs to read a property. Now as the method is called from untrusted restricted code, it is itself restricted and thus reading the property would fail. But of course the framework trusts itself and wants itself to be able to read that property, even in the case that somewhere in the call stack is untrusted code. That's when you need to use doPrivileged. It basically says "no matter what is up there in the call stack, I am a piece of framework code, and I am allowed to do whatever the framework code is allowed to do". So reading the property using the second method succeeds.

Of course one needs to be careful when using doPrivileged in order to not let the (untrusted) calling code do to much. If, for example, the framework code offers the following method to the plugin:

public String getProp(String key) {
  return (String) java.security.AccessController.doPrivileged(
           new sun.security.action.GetPropertyAction(key));
}

this would completely invalidate the policy that the untrusted code is not allowed to read system properties, because it can just use your method.

So use this method only when you know it is safe to do it, and only when you need it (which is, when you want your code to be able to do more than some other code should be able to do directly). Inside a normal application (which usually runs with no SecurityManager or the same security context for all code), there is no difference and the first method should be used.



回答2:

I would recommend to stick with System.getProperty() since sun.security.action.GetPropertyAction seems to be proprietary to SUN and will not work on all Java VM implementations. Even the compiler warns you about it as:

warning: sun.security.action.GetPropertyAction is Sun proprietary API and may be removed in a future release

To understand what it actually means see this answer.



回答3:

The reason to use a class like sun.security.action.GetPropertyAction is to avoid loading several, basically identical classes.

If you wrote:

(String) java.security.AccessController.doPrivileged(
   new java.security.PrivilegedAction<java.lang.String>() {
      String run() {
         System.getProperty("property");
       }
   }
 );

Each time you wanted to get a system property, you would load a new class for each getProperty call. Each class takes system resources and lives as long as the containing ClassLoader (forever for the bootclassloader).

Check out the javap output for more details:

javap -c -v -p sun.security.action.GetPropertyAction