In java to pass the values between some classes we can use System.setProperty. But using System.getProperties() we can get all the system properties. So if i use any third party API's means they can also access my properties and also they can change. SO is System.setProperty safe ?
问题:
回答1:
It depends what you mean by safe.
It is good practice1 treat the System Properties object as read only, but you can't rely on 3rd-party libraries to do that.
If you are worried about "trusted" 3rd-party code seeing or changing your application's properties, don't use System Properties to represent them. Create your own Properties object and put your properties there. This is probably the simplest approach overall.
If you use sandboxing, you can prevent untrusted code from access the System Properties ... provided that your code doesn't leak the System Properties object to the untrusted code. (The access checks are implemented in the
System
methods ...)A Properties object is thread-safe ... if you are referring to that kind of safety.
1 - Occasionally it is necessary to modify system properties programmatically. However, you can end up with fragile applications by doing this. The system properties are typically used to configure JVM services during the initialization. If the order of class initialization changes for some reason, you could find that your application code is now setting the properties too late. If possible, it is better to set the properties via -D
command line parameters.
回答2:
If you need to worry about the behavior of libraries, you need to learn about and use a security policy and a SecurityManager. Amongst other things, this will allow you to restrict the use of System.setProperty
.
回答3:
As per the documentation
In general, be careful not to overwrite system properties.
The setProperties method changes the set of system properties for the current running application. These changes are not persistent. That is, changing the system properties within an application will not affect future invocations of the Java interpreter for this or any other application. The runtime system re-initializes the system properties each time its starts up. If changes to system properties are to be persistent, then the application must write the values to some file before exiting and read them in again upon startup.
your concern is correct that some third party libraries might overwrite the properties that your app is using. Its always a good practice to use some naming convention to distinguish keys defined in your property file.
A very simple simulation of the problem
public class TestApp {
public static void main(String args[]) throws InterruptedException {
TestApp app = new TestApp();
app.new ThirdPartyLib("thirdParty").start();
while (true) {
Thread.currentThread().sleep(500);
System.setProperty("test", "orignalProperty");
System.out
.format("Thread Name '%s' setting the property with value '%s' \n ",
Thread.currentThread().getName(),
System.getProperty("test"));
}
}
class ThirdPartyLib extends Thread {
public ThirdPartyLib(String threadName) {
super(threadName);
}
@Override
public void run() {
super.run();
while (true) {
Thread.currentThread();
try {
Thread.sleep(400);
System.setProperty("test", "modifiedProperty");
System.out
.format("Thread Name '%s' setting the property with value '%s' \n ",
Thread.currentThread().getName(),
System.getProperty("test"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
will result in output below - which might not be the intended one and I am sure difficult to debug also
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'main' setting the property with value 'orignalProperty'
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'main' setting the property with value 'orignalProperty'
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'main' setting the property with value 'orignalProperty'