Java - Can .properties values be set statically in compiled class? - java

Can .properties values be stored statically in compiled classes?
I am updating a value in my .properties file yet the log is still showing the old value from the original .properties file. Is this because the class file has stored the .properties values during compilation? (I do not have the original source so cannot recompile)

Properties are not set statically in compiled class. Most likely you have old properties somewhere in classpath, or, maybe, another property file with the same property. Try to run your application in verbose mode in order to get classpath and search in it for properties files loaded.

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.

Properties file vs environment variable

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)

Adding properties file to java classpath at runtime

My code generates few properties file at runtime and these will be used by other portion of code.But the other portion of code expects that those properties files in the classpath.
Is there any way to generate the files in classpath at runtime.
You could simply create empty files which are set on the classpath up front and the application appends to these as necessary.
I'm wondering though, do you need to touch the hard disk at all? Could you not use a cache instead?

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.

log4j picking up wrong properties file

There are 2 log4j.properties files in my classpath. I need both of them - One of them is required for a library that I am using and another is the one used by my code. When I run my jar file, it is able to read the properties used by the library, but it is not reading my own properties file. How can I make it read my log4j without having to use PropertytConfigurator in all my source files? Is there any way I can configure it so that it used both the properties files together?
To answer your first question, you can point it to your own file by giving it a unique name and adding the following system property when you launch your application.
-Dlog4j.configuration=path_to_my_properties_file
I don't think it is possible to use 2 different files without doing anything programatically.
Two log4j.properties files will surely create a mess (as you've experienced).
I'd suggest removing the library's version (why is it a requirement?), and combining both .properties files into one.
All logging goes into a single property file. Within that file you can differentiate between your own classes and the library's logging configuration.

Categories