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 ?
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.
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.
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'
I wouldn't rely on using System properties to share info between threads. I tried creating a property in one thread, another thread couldn't find even after 10 seconds had elapsed. Behavior of modifying values of system properties already available to threads has been answered by others.
Related
I have a configuration which if enables blocks unknown variables from passing through.
#Value("${json.failOnUnknown:false}")
private boolean failOnUnknown;
Jackson2ObjectMapperBuilder build = new Jackson2ObjectMapperBuilder();
if(!failOnUnknown) {
build.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
else {
build.featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
I want this so if someone sends a bad property to my service I block them. However, my service connects to other services and if they send in an unknown variable it fails as well. I want unknown variables to be ignored when my other services talk to my current service.
I have tried using
#JsonIgnoreProperties(ignoreUnknown=true)
To overwrite the FAIL_ON_UNKNOWN_PROPERTIES but it doesn't work.
Any ideas on how to block unknown variables in some classes and not others?
One solution you might get into is to create two separate ObjectMappers, one that ignores unknown properties and the other one that throws exceptions. You can disable fail on unknow property directly on your Object Mapper scope as following: objectMapper.disable(FAIL_ON_UNKNOWN_PROPERTIES);.
The idea is that you could still create a global scoped object mapper as shown in your example you use almost everywhere except for those services that needs to fail on unknown properties whatever the context is.
I want to create a framework that shows the application name on statup. Targeting command line interface applications.
Question: how can I get such an application name in a generic way?
Eg spring offers a property, but which is not set by default:
#Value("${spring.application.name}")
private String appname;
And I don't want to set that property explicit. Looking for some kind of "default application name".
In a Java EE container there is also the following option:
String myApplicationName = (String) initialContext.lookup("java:app/AppName");
But how about CLI apps? How can I get some kind of generic application name?
The closest you can get, if I interpreted correctly your question, is to:
find which class is running public static void main(String [] args) method
get its simpleName
store aforementioned name into a system property
and in order to do so, you have two options:
call Thread.currentThread().getStackTrace(), and inspect its tail element. But this has to be executed in the main thread as well, otherwise you wont retrieve the correct StackTraceElement;
call Thread:getAllStackTraces(), and parse the entire map to identify the main Thread, get the corresponding value, and pick its last StackTraceElement
Once you have StackTraceElement, you can call StackTraceElement:getClassName() which will return something like
scala.tools.nsc.MainGenericRunner
Split the string, save it into a system property, and you're good to go.
Hope it will help you.
I have the class similar to the following:
#Component(configurationPid = "foo.bar", configurationPolicy = ConfigurationPolicy.REQUIRE)
public class MyClass {
#Activate
public void activate(Map<String, Object> properties) throws Exception {
for (String property : properties.keySet()) {
if (!isValidProperty(property)) {
throw new IllegalArgumentException("Unknown property: " + property);
}
...
}
}
}
The properties map must contain the properties from the corresponding configuration source (e.g. a file provided by an user). And it is, but it also contains some properties that are not really exist (service.pid, felix.fileinstall.dir, etc.), so my program is broken. I want to get rid of them somehow.
I tried to use ConfigurationAdmin.getConfiguration.getProperties and also blueprint cm-properties but this gives the same effect.
I can't hardcode the names of the properties to exclude, because I don't know what they are.
Is there any means to tell the OSGi runtime not to put them at all in my map?
I'm doing this using ServiceMix's OSGi support (which is essentially Karaf, Felix, and Aries).
Just ignore the properties you don't like/understand. The system is designed so that the party doing the configuration can add any property and that property will be passed to your component and thus be a service property on your component's service. Removing the properties you, the component developer, don't understand is overly restrictive. You would remove the ability of someone in the deployment process from decorating your service in a way meaningful to someone else.
Currently there is no way to exclude these artificial properties but I agree this is pretty bad.
You can open an issue and the Apache felix project jira.
We're developing a Java application that reads a Config file at runtime. My question is that which of the following scenario is efficient for reading a Config file.
Scenario #1: Retrieves a value from config by opening the file, get the value, then close the file.
So this means that file will be open and close every time retrieving a value.
Scenario #2: Open the file during initialization, then expose the object statically across the runtime.
File will be open once, then retrieving a value using the Config object.
Honestly, we currently using the scenario #2. A reason why we choose it because Config file will be open once. Opening file needs syncrhonization, which may lead to untimely retrieval of value. Also, scenario #1 may cause runtime error if the Config file is moved from it's absolute path (anything is possible). But scenario #1 is efficient when it comes in modifying the Config values during runtime.
So which is efficient?
Is your application a mulit-threaded application? if yes, you need to make sure that you have scenario #1 with necessary synchronisation and semaphores. The reason is that your config file is a general item in your application which will be used by all the threads. You don't want the config file reading operation to be interleaved. Even with single threaded operation, it is good to do #1 because you will have less chances of having IO Error. The RTE that you mentioned in your question can happen with anything if you decide to move the file (? Why would you if you need it at a certain place?).
If I should have to access the file more than once, probably I would create a class with a field for each configuration, I would read the file once (only to initialize the class fields) and then I would close the file. In this way you read the file once, during the init, and then you could simply access the configuration by reading the field values stored in the class.
public class Configuration
{
private static String confOne;
private static int confTwo;
private static boolean confThree;
public static init(File configFile) {
/* read the file and init fields */
}
public static String getConfigOne() {
return configOne;
}
public static int getConfigTwo() {
return configOne;
}
public static boolean getConfigThree() {
return configOne;
}
}
A little advice: tries to never hold open a file (or resources) unless absolutely necessary.
I think neither of the scenarios is the best one:
As you you have already stated in sencario #1 you may have a lot of unnecessary IO-Workload and in #2 you cannot change config parameters dynamically at runtime.
I suggest to use a mixture of both. You can load your configuration statically once and then check periodically, if changes have happend. If so, reload your config.
You can see how it may be done by inspecting Java's ResourceBundle-Class. In fact, if the config can be placed as properties-file in your classpath, you can (ab?)use this implementation for your purpose:
private static Control MY_CONTROL = new Control()
{
#Override
public long getTimeToLive(String baseName, Locale locale)
{
return MY_TTL; //make shure, that changes are checked periodically
}
};
public static String getParamter(String name)
{
ResourceBundle config = ResourceBundle.getBundle("config", MY_CONTROL);
return config.getString(name);
}
I have to access some application through an mbean so that I can change its application properties. Now i think this can be done in two ways:
First, either I ask the developer of that application to register all the application properties in an arraylist which my mbean will access.
Secondly, if there is any other way, such that the developer will only need to register editable properties and still my mbean can access both readable/editable(r/w) application properties.
Now since I don't know where these application properties are stored in the JVM, is there a way to implement my second point so that the mbean will just need to access that object and it will get all application properties?
Seems like you have some contradicting requirements here.
You want to change minimal code in the application.
You want to be cause to expose all properties for read and/or write.
You may or may not be talking about System.getProperty(...). If not then I guess you are talking about just fields in various objects.
There are (at least) two ways of doing this. Without knowing how you are exporting the mbeans from the source code right now, I can't tailor my answer to your specific config. My answer will instead show how you might use my SimpleJMX package to expose your properties.
If you are talking about System.getProperty(...) then you could write a JMX mbean that could query any property and return the value:
#JmxOperation(description = "Query for property")
public String queryForProperty(String name) {
return System.getProperty(name);
}
If, instead, you need to export of fields from some list of objects then you are going to either have to add annotations to each fields you are exporting or you are going to have to write beans that export the fields through delegation. I see no easy way and I know of no package that will easily export a series of objects for you without some sort of information about what is to be exported and how.
Using SimpleJMX, you can export a field by annotating either the field or the get method:
#JmxAttributeField(description = "Number of hits in the cache")
private int hitCount;
...
// this can also be specified as #JmxAttributeMethod on the getter/setter methods
#JmxAttributeMethod(description = "Number of misses in the cache")
private int getMissCount() {
return missCount;
}
The #JmxAttributeField supports a isWritable = true to allow the value to be set by JMX. You can also annotation the setter with #JmxAttributeMethod to make it writable.
If you don't want to add annotations to each of your classes, then you are going to have to write some sort of JMX container class that exports the values through delegation:
public class JmxPublisher {
private Class1 object1;
private Class2 object2;
...
public JmxPublisher(Class1 object1, Class2 object2) {
this.object1 = object1;
this.object2 = object2;
...
}
#JmxAttributeMethod(description = "Number of hits in the cache")
public int getClass1HitCount() {
return object1.getHitCount();
}
#JmxAttributeMethod(description = "Shutdown the background thread")
public void setClass2Shutdown(boolean shutdown) {
return object2.setShutdown(shutdown);
}
...
}
I also think you should express yourself more clearly.
From what I understood - why not providing a way to query the remote application, and get information on all properties and if they are Read-only, Write-only or RW?
This way the list of properties will not be mentioned at the source code of the client application - maybe you should let the user of the client application see the list of properties, and let him edit the properties he can edit, and prevent him from editing the properties he can't.