Java System Properties and Environment Variables

Java system properties and environment variables

I think the difference between the two boils down to access. Environment variables are accessible by any process and Java system properties are only accessible by the process they are added to.

Also as Bohemian stated, env variables are set in the OS (however they 'can' be set through Java) and system properties are passed as command line options or set via setProperty().

difference between environment variables and System properties

Environment variables is an OS concept, and are passed by the program that starts your Java program.

That is usually the OS, e.g. double-click in an explorer window or running command in a command prompt, so you get the OS-managed list of environment variables.

If another program starts your Java program1, e.g. an IDE (Eclipse, IntelliJ, NetBeans, ...) or a build tool (Maven, Groovy, ...), it can modify the list of environment variables, usually by adding more. E.g. the environment variable named MAVEN_CMD_LINE_ARGS would tend to indicate that you might be running your program with Maven.

In a running Java program, the list of environment variables cannot be modified.


System properties is a Java concept. The JVM will automatically assign a lot of
system properties on startup.

You can add/override the values on startup by using the -D command-line argument.

In a running Java program, the list of system properties can be modified by the program itself, though that is generally a bad idea.


1) For reference, if a Java program wants to start another Java program, it will generally use a ProcessBuilder to set that up. The environment variables of the new Java process will by default be the same as the current Java program, but can be modified for the new Java program by calling the environment() method of the builder.

When to use environment variables vs. system properties?

If you are using Java 1.3 or 1.4 (and 1.2, IIRC), you should be using system properties, since System.getenv was deprecated. It was reinstated in Java 1.5. The relevant bug report can be found here.

You can use both. Search system properties for the key, and if it's not there, search the environment. This gives you the best of both worlds.

These really aren't the same thing: One requires the value to be set explicitly, and the other not. Also, note that the environment is a convenient place to put some strings for interoperability.

Environment variables not converted to system properties

You are using the (now deprecated) PropertyPlaceholderConfigurer while that can consult the system environment it lacks the feature of mapping those properties to values. I.e HOST_SERVICE_BASE_URL isn't mapped as host.service.base.url.

That support is only available in the SystemEnvironmentPropertySource which is automatically registered and consulted when using the PropertySourcesPlaceholderConfigurer (recommended as of Spring 5.2, but available since 3.1).

<bean id="dataConfigPropertyConfigurer"
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="properties" ref="applicationProperties"/>
</bean>

Or in Java to replace the applicationProperties bean and XML portion.

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocations({"/WEB-INF/config/application.properties", /WEB-INF/config/application-dev.properties"});
configurer.setIgnoreResourceNotFound(true);
return configurer;
}

Or if you really stick with XML use the <context:property-placeholder /> tag, which automatically does this.

<context:property-placeholder properties="applicationProperties" ignore-resource-not-found="true" />

or

<context:property-placeholder locations="/WEB-INF/config/application.properties,/WEB-INF/config/application-dev.properties" ignore-resource-not-found="true" />

What's the difference between a System property and environment variable

Environment variables are specific to the operating system. Properties are JVM only.

Reading Java system properties from command line

You can use the -XshowSettings flag in the Hotspot JVM version 1.7 and up (not supported in 1.6):

java -XshowSettings:properties -version

OpenJDK has had support for this flag since late 2010.

Seen in http://marxsoftware.blogspot.de/2016/02/hotspot-jvm-XshowSettings.html

EDIT 14 Dec 2016

The Oracle JVM ships with the tool jcmd which allows you to see the flags present in a running JVM. See:

https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html

For this use case, you could use:

jcmd <pid> VM.system_properties

But there are also many other useful commands. For example:

jcmd <pid> VM.flags
jcmd <pid> VM.command_line
jcmd <pid> GC.run

Regarding application.properties file and environment variable

You can put environment variables in your properties file, but Java will not automatically recognise them as environment variables and therefore will not resolve them.

In order to do this you will have to parse the values and resolve any environment variables you find.

You can get at environment variables from Java using various methods. For example: Map<String, String> env = System.getenv();

There's a basic tutorial here: http://java.sun.com/docs/books/tutorial/essential/environment/env.html

Hope that's of some help.

karaf - how to add environmental variable in system.properties file

There are couple of ways we can achieve this, what i did was,

1) Exported EXTRA_JAVA_OPTS as,

export EXTRA_JAVA_OPTS="$EXTRA_JAVA_OPTS -Dapp.name=myApp"

then used the same in system.propeties file,

karaf.lock.jdbc.clustername=${app.name}

2) Even we can directly export the karaf varaible to EXTRA_JAVA_OPTS
export EXTRA_JAVA_OPTS="$EXTRA_JAVA_OPTS -Dkaraf.lock.jdbc.clustername=myApp"
//i have not tried, it should work



Related Topics



Leave a reply



Submit