GetPropertyAction vs系统。获取系统变量的getProperty

时间:2021-11-10 11:47:26

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 :

为了获得环境信息。然而,在我看来,Sun更喜欢以下几点:

(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

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

实现,它只使用安全管理器,然后立即从实例变量支柱中获取属性。我的问题是,为什么Sun选择使用第二种方法来在内部获取代码中的大多数环境变量

System.getProperty

System.getProperty

seems like the faster way to go?

似乎是更快的方法?

3 个解决方案

#1


8  

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."

getproperty(“property”)的代码System.getProperty(“property”)表示,“如果当前的安全上下文允许我读取属性的值,那么请将该属性的值给我。”

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."

使用doPrivileged的代码说:“如果允许当前类(这行代码所在的类)读取属性的值,那么就给我这个属性的值。”

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.

例如,考虑一个执行插件代码的框架,它是不受信任的。因此框架使用SecurityManager来限制不受信任的插件代码的操作。当然,插件可能会调用框架的一些方法,并假设其中一个方法需要读取属性。现在,当方法从不受信任的受限代码中调用时,它本身就受到限制,因此读取属性将失败。但是,框架当然信任自己,并希望自己能够读取该属性,即使在调用堆栈中的某个地方是不受信任的代码的情况下也是如此。这时你需要使用多巴胺。它基本上说“无论调用堆栈中有什么,我都是一段框架代码,允许我做框架代码允许做的任何事情”。因此,使用第二个方法读取属性是成功的。

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:

当然,在使用doPrivileged时要小心,以免(不可信的)调用代码造成太大的影响。例如,如果框架代码为插件提供以下方法:

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.

因此,只有当您知道这样做是安全的,并且只有当您需要它时(也就是说,当您希望您的代码能够比其他代码能够直接做的更多时),才可以使用这个方法。在正常的应用程序中(通常在没有SecurityManager或所有代码的相同安全上下文的情况下运行),没有区别,应该使用第一个方法。

#2


1  

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:

我建议继续使用System.getProperty(),因为sun.security.action。GetPropertyAction似乎是SUN专有的,不会在所有Java VM实现上工作。甚至编译器也会警告您:

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

警告:sun.security.action。GetPropertyAction是Sun的私有API,可能在以后的版本中被删除

To understand what it actually means see this answer.

要理解它的真正含义,请看这个答案。

#3


0  

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

使用像sun.security.action这样的类的原因。GetPropertyAction避免加载几个基本相同的类。

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).

每当您希望获得系统属性时,您将为每个getProperty调用加载一个新类。每个类只要包含类装入器(始终为引导类装入器),就会占用系统资源和生命。

Check out the javap output for more details:

查看javap输出了解更多细节:

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

#1


8  

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."

getproperty(“property”)的代码System.getProperty(“property”)表示,“如果当前的安全上下文允许我读取属性的值,那么请将该属性的值给我。”

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."

使用doPrivileged的代码说:“如果允许当前类(这行代码所在的类)读取属性的值,那么就给我这个属性的值。”

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.

例如,考虑一个执行插件代码的框架,它是不受信任的。因此框架使用SecurityManager来限制不受信任的插件代码的操作。当然,插件可能会调用框架的一些方法,并假设其中一个方法需要读取属性。现在,当方法从不受信任的受限代码中调用时,它本身就受到限制,因此读取属性将失败。但是,框架当然信任自己,并希望自己能够读取该属性,即使在调用堆栈中的某个地方是不受信任的代码的情况下也是如此。这时你需要使用多巴胺。它基本上说“无论调用堆栈中有什么,我都是一段框架代码,允许我做框架代码允许做的任何事情”。因此,使用第二个方法读取属性是成功的。

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:

当然,在使用doPrivileged时要小心,以免(不可信的)调用代码造成太大的影响。例如,如果框架代码为插件提供以下方法:

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.

因此,只有当您知道这样做是安全的,并且只有当您需要它时(也就是说,当您希望您的代码能够比其他代码能够直接做的更多时),才可以使用这个方法。在正常的应用程序中(通常在没有SecurityManager或所有代码的相同安全上下文的情况下运行),没有区别,应该使用第一个方法。

#2


1  

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:

我建议继续使用System.getProperty(),因为sun.security.action。GetPropertyAction似乎是SUN专有的,不会在所有Java VM实现上工作。甚至编译器也会警告您:

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

警告:sun.security.action。GetPropertyAction是Sun的私有API,可能在以后的版本中被删除

To understand what it actually means see this answer.

要理解它的真正含义,请看这个答案。

#3


0  

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

使用像sun.security.action这样的类的原因。GetPropertyAction避免加载几个基本相同的类。

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).

每当您希望获得系统属性时,您将为每个getProperty调用加载一个新类。每个类只要包含类装入器(始终为引导类装入器),就会占用系统资源和生命。

Check out the javap output for more details:

查看javap输出了解更多细节:

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