Properties file vs environment variable - java

Hey i wondered what is the difference between .properties file to environment variable in java.
.Properties file
arg1=text1
arg2=text2
environment variable
java -jar -arg1=text1 -arg2=text2 myJAR.jar

Passing arguments in this way is not overridable at runtime :
java -jar -arg1=text1 -arg2=text2 myJAR.jar
as the values are passed when the application is started.
You have to restart the application to change the values.
Besides, passing a lot of arguments may be error prone.
Valuing properties in this way may be overridable at runtime :
.Properties file
arg1=text1
arg2=text2
As the values are located in a external file that may be modified during the runtime of the application. Of course a way foreseen to take into consideration the file modification during the runtime has to be implemented in the application.
For example, Logback (with Joran implementation) provides a way
to change the Logback configuration file at runtime :
https://logback.qos.ch/manual/configuration.html#joranDirectly

Environment variables are key-value pairs passed to a program while it's invoked whereas properties file consists of list of properties along with their values. Generally, properties file is considered to be the best practice to maintain configuration values, here's why:
Properties file are more readable than environment variables. Also, they are not tied to startup script, we can pass any file while running the program.
Frameworks like Spring provide different ways to create a collection or map from properties file.
It's easy to use different properties files for different environments (e.g. stage, prod etc)

Related

Use single profile-specific property file from multiple application.properties files

I have a few spring-boot microservices and I want to use a single profile-specific property file for all the microservices. profile-specific property file should be outside of the jars.
example:
The application-common-profile.properties file and jar files are inside the same folder
java -jar Microservice-1.jar --spring.config.location=classpath:/application.properties --spring.profiles.active=common-profile
java -jar Microservice-2.jar --spring.config.location=classpath:/application.properties --spring.profiles.active=common-profile
the above commands won't take the common-profile properties. please help to achieve this. Thanks.
IMPORTANT DETAILS
This jar file doesn't contain 'application-common-profile.properties' file. this file resides outside the jar but in the same folder. if I put my 'application.properties' file inside the same foder then it is working(retrieving the properties) with the below command.
java -jar Microservice-1.jar --spring.config.location=C:/folderpath/ --spring.profiles.active=common-profile
I can place other microservices 'application.properties' files in same folder with different names(ex: application-microservice-2.properties). and also the profile property files with different names.(ex: application-microservice-2-common.properties ) It's okay having different application.properties files. but need to have one common profile property file.
FIXED
I added common profile property file(application-common.properties) and jars in same folder and run below commands simply and it is working. I think adding unnecessary arguments was the problem.
java -jar Microservice-1.jar --spring.profiles.active=common
java -jar Microservice-2.jar --spring.profiles.active=common
If your application.properties file is bundled in your jar, then simply adding the profile-specific property file to your working directory will allow it to be picked up. However, when you set spring.config.location you're overriding the path that Spring will look up these properties from, you should drop this, it's not necessary. Spring will look in your working directory for the properties files by default if they're not bundled in the jar.
Personally, I would avoid trying to maintain the property files in the environments in favor of environment variables.
Bundle your jar with the top-level application.properties included in it, and for the variables that are different given the environment, set environment variables for them.
e.g. if you want to override spring.datasource.driver-class-name, set the environment variable SPRING_DATASOURCE_DRIVER_CLASS_NAME. I think you'll find this approach is far more flexible.

log4j Properties File pick

Observed a rather strange behaviour from apache log4j and thought sharing to get your thoughts.
I have an application which I'm running using an script. So far nothing special about that.
But the CLASSPATH I'm setting using that script, say a directory /home/myName/, have two different log4j properties files. One is simply log4j.properties and other is log4jXYZ.prperties.
The strange thing is when I run this script from different directories, one or the other log4j properties file is being picked-up. My understanding was it should have picked log4j.properties, obviously irrespectively from whereever I run the script.
Do you see some logic which can make a sense of it. Currently I'm at loss.
What I can predict is that log4j is trying any file matching lo4j*.properties expression.I must admit I haven't read all the manual assisting log4j.
Add log4j.debug property, when you run the application (-Dlog4j.debug= for the java command), it should show you the path where it loads the config file from.
I suspect it may load a file with same name from another directory than you think.

How to configure logging when running a JAR?

I am new to Java logging API and need some help with this problem:
While creating the application, my config file was stored in the project root folder, so I used -Djava.util.logging.config.file=logging.properties switch to run the program.
But then I exported the executable JAR.
How to configure the logging now? It doesn't work, when I specify the path to config file with the -D switch.
You can't specify JVM arguments into the MANIFEST.MF file so you have to specify the logging properties at the command line or with a shortcut :
java -Djava.util.logging.config.file=logging.properties -jar yourjar.jar
Otherwise you could package a properties file(logging.properties in your case) in the JAR, read that at
startup and put those settings into the system properties.
The javadoc says:
In addition, the LogManager uses two optional system properties that
allow more control over reading the initial configuration:
"java.util.logging.config.class"
"java.util.logging.config.file"
These two properties may be set via the Preferences API, or as command
line property definitions to the "java" command, or as system property
definitions passed to JNI_CreateJavaVM.
If the "java.util.logging.config.class" property is set, then the
property value is treated as a class name. The given class will be
loaded, an object will be instantiated, and that object's constructor
is responsible for reading in the initial configuration. (That object
may use other system properties to control its configuration.) The
alternate configuration class can use readConfiguration(InputStream)
to define properties in the LogManager.
So, either use the java.util.logging.config.file system property, and store the config file out of the jar file (which is probably a good idea if you want to be able to customize the logging properties in order to debug or analyze some weird behavior), or store the config file wherever you want (in the jar file, for example), and use the java.util.logging.config.class system property to load and instantiate a class that will read the file in the jar file (Using Class.getResourceAsStream()).
I know it's little late to answer this question but I ran into this issue few days back with the runnable jar and I solved it like this:
java -Djava.util.logging.config.file=logging.properties -cp test.jar com.sample.test.Main
where test.jar is the name of your jar and com.sample.test.Main is the fully qualified name of your main class.

Use Eclipse classpath variables in Java code

Is it possible to use Eclipse's classpath variables within in Java code? I have several bin directories for multiple projects that are defined in classpath variables, and need to reference them multiple times within one of my projects.
Tying something unique to an IDE to your application code is not particularly good practice. Try instead to make use of system properties, environment variables or the -D arguments to the application.

PHP Environment variable

I am using PHP Java Bridgeon a windows and linux server. Now I want to modify the
CLASSPATH. When I do a phpinfo(), I see a CLASSPATH under environment variables section and
when I output the java.lang.system properties there is a property called java.class.path.
First of all what is the difference between the two? How do I modify both of them? Can they be modified programatically ?
I don't know about the phpinfo() information, but the System.property can't be set (to any effect) directly. It is effectively read-only and taken from the environment CLASSPATH variable and -classpath command line option when Java is launched.
You can effectively change the classpath used to load classes by creating your own classloaders or class loader instances (see URLClassLoader) and using it to load from dynamic locations.

Categories