How to read different property files for different environment? - java

I have a web application created in maven. I am using tomcat server on my local as well as on dev unix box. I need to use two different .properties file like local.properties and dev.properties (may be in different folders). My doubt is 'How can we configure the tomcat of local and the tomcat of unix box to read different properties file at the time of deployment?' What are different ways for it.

The easiest and out of the box solution you can use with spring is to have two files, named application-dev.properties and application-prod.properties which will be activated if if you pass -Dspring.profiles.active=dev or prod. You pass this parameter when deploying the app. No configuration, no annotation, no xml. As long as you keep the naming convention application-something.properties

Easiest is pass a system parameter to your JVM to identify the environment, then package up a dev.properties and local.properties in the jar.
#PropertySource(value = {"classpath:local.properties", "classpath:${ENVX}.properties"}, ignoreResourceNotFound = true)
Use a -DENVX=dev for dev (add to your tomcat script), if it is not specified local.properties will be picked up.

Related

How pass log4j2.xml to Tomcat application

I have application which is running at Tomcat 8 server.
Application use log4j2 for internal logging.
I want to have one application.war and two different log config files like:
log4j2_dev.xml and log4j2_prod.xml depending from environment.
In production environment I want deploy application.war and use log4j2_prod.xml
And in development environment I want deploy application.war and use log4j2_dev.xml
So, how could I specify which file to use during application.war deploying?
PS.
I don't want build two different wars like
application_prod.war and application_dev.war with different configs inside.
Maybe you could specify in your build which config file to use?
E.g. -Dlog4j.configurationFile={path to file}, where path would be determined by building dev or prod?
In the $CATALINA_BASE/bin/setenv.sh file I've added the line:
export LOG4J_CONFIGURATION_FILE=/dev/log4j2_dev.xml

Read updated configurations from application.properties without repackaging the uber jar

Is there a way to read the updated changes in application.properties without repackaging the jar in Quarkus? I could not find anything related in the official documentation at https://quarkus.io/guides/config-reference. So I am assuming that the uber jar has the application properties built in. So is there a way to override those configs while running the jar?
Edit: What I mean by overriding is: Is there a way to specify the path of the config file that the jar reads while running the jar. Something similar to java -jar app.jar -DConfig='/path/to/application.properties'.
In Quarkus some of the configurations are fixed at build time, (the once in the documentation with the lock). Others are not, this ones you can change them at runtime using several methods, for example, using environmental variables or properties in the launch commands.
Check this links for more information:
https://quarkus.io/guides/config#build-time-configuration
https://quarkus.io/guides/config-reference#configuration-sources
As you can see in the configuration-source section, quarkus will firstly search in system properties and other sources rather than in the application properties file, there is one possibility for you to change the value of your properties.

Spring Boot Properties Outside FAT JAR

I'm working on a project and have a use case where I need to provide application.properties file for Spring Boot from outside the JAR.
According to Baeldung, the priority order for picking up the application.properties is
A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root
The issue with first two is I'll need to navigate to the directory containg the configs to run the JAR. It sounds no issue when working on local but wont be a feasible solution when deploying on remote hosts as through CI/CD frameworks.
I'm trying to find a mechanism using classpaths and avoid using spring boot's command line options mentioned over here or setting up environment variables.
I'm unable to figure out how to setup classpath while running FAT JAR and specify configs all together. If you can, please help me figure it out!
Thanks in advance :)
EDIT : I understand there are ways to achieve this using Spring Boot's command line options such as spring.config or loader.path etc.
I was trying to find a more implicit solution based on classpath and directory structures only to make it less coupled with the fact that Spring Boot is being used.
According to the Spring docs, you can define external config locations using the spring.config.location property. More specifically:
If spring.config.location contains directories (as opposed to files),
they should end in / (and, at runtime, be appended with the names
generated from spring.config.name before being loaded, including
profile-specific file names).
Files specified in
spring.config.location are used as-is, with no support for
profile-specific variants, and are overridden by any profile-specific
properties.
Config locations are searched in reverse order. By default, the
configured locations are:
classpath:/,classpath:/config/,file:./,file:./config/.
The resulting
search order is the following:
file:./config/ file:./ classpath:/config/ classpath:/
When custom
config locations are configured by using spring.config.location, they
replace the default locations. For example, if spring.config.location
is configured with the value
classpath:/custom-config/,file:./custom-config/
the search order
becomes the following:
file:./custom-config/ classpath:custom-config/
Alternatively, when
custom config locations are configured by using
spring.config.additional-location, they are used in addition to the
default locations.
Additional locations are searched before the
default locations. For example, if additional locations of
classpath:/custom-config/,file:./custom-config/
are configured, the
search order becomes the following:
file:./custom-config/ classpath:custom-config/ file:./config/ file:./ classpath:/config/ classpath:/
An example usage for a directory containing your external configi would look like:
java -jar myproject.jar --spring.config.location=file:/custom-config-dir/
Or directly to an external config file:
java -jar myproject.jar --spring.config.location=file:/custom-config-dir/custom-config.properties
Specify custom config location as VM argument is another option.
java -Dspring.config.location=<config-dir-path> -jar demo.jar

log4j is not working in weblogic server?

I am using weblogic 10.3.4, I am trying to write log with log4j. but at runtime my application is not getting any log4j.properties. even this is not generating any warning as "initialization of log4j has error".
I have tried my properties file to put in src folder, classes folder and then I created one jar and put it in domain lib. still its not picking. even when I am writing log with same jar in standalone application, its working fine.
please help me with valuable suggestions.
I tried the solution proposed at Oracle forums.
Excerpt from that link at Oracle forums:
I've only modified the scritp startWebLogic.cmd:
set LOG4J_CONFIG_FILE=log4j.xml
set SAVE_JAVA_OPTIONS=%JAVA_OPTIONS% -Dlog4j.configuration=%LOG4J_CONFIG_FILE%
#REM set SAVE_CLASSPATH=%CLASSPATH%
set SAVE_CLASSPATH=%CLASSPATH%;C:\Oracle\Middleware\user_projects\domains\domain\config
In this way I've put all the config folder inside the classpath, and I can use it in future to hold other libraries configuration files (for example oracle coherence config).
I tried this approach on a different properties file as well and that worked well!
You need to either specify where the application should find its log4j.properties, or put it onto the classpath of the application. Where the classpath is varies, but in general WEB-INF/classes should work. Other options depend upon how you're deploying the application.
A better long term strategy is to configure your system so that you can change the log4j.properties depending upon the environment. When you're in production, you won't want all of the debug information to appear. Look at the answer to this question or this question for more ideas. One strategy is to define a variable on the command line which gets picked up and defines a directory which contains your configuration files. This works for Tomcat, but there may be other, better, strategies for Weblogic.
It is not a good idea to change the configuration of your server, in particular, don't replace the log4j.jar or log4j.properties in your server directories. The server will depend upon the version that it was designed to use, which may or may not be the same as your version. You can do everything you need to do by changing the war that you're deploying.
I have used this code:
ClassLoader cl = this.getClass().getClassLoader();
URL log4jCfg = cl.getResource(configFile);
if (log4jCfg != null) {
DOMConfigurator.configure(log4jCfg);
}
log.info("log4j is now working on Web App.");
In my case, we used XML configuration:
log4jCfg = "mylog4j.xml";
In WebLogic, we were able to place such file (mylog4j.xml), equivalent to your log4j.properties file, at WebLogic's domain path (specific to the domain were we deploy). This means that domain folder belongs to your application's path. I just tested it with Web applications, I'm not sure if with SOA or EJB projects it works the same way.
When you deploy any application on any server that application should use servers log4j jar.
So if you have added any log4j jar in your application jar/tar/ear, remove it and copy log4j.properties file in the conf folder of the server from where server is picking its configuration files. Or just copy your log4j property content in servers log4j property file.

different configuration files for different server

Hi How would you solved that?
I have one application in which I have a few configuration files, I make war file and deploy it on the tomcat.
But at the same time I have to make the war file and deploy the same application under different context and/or a server with modified configuration files.
I can create my own task in ant, and replace needed paramaters but there can be possibility of moving to maven, and anyway I'm not sure about it. Or can I use something like spring's property place holder configurer or jgroups
Spring can handle this quite well in a variety of ways. The approach I found most useful and flexible is to setup in each environment a system variable that specifies trhe environment name e.g. test, dev, int, prod, etc.
Spring can then use this system variable to load the correct property files. Depending on your needs these property files can be bundled with the app or loaded from an external location. Theres an example of a similar approach here:
http://www.developer.com/java/ent/print.php/3811931
I'd deploy Spring apps packaged as a WAR to either Tomcat or WebLogic without any changes. It would contain both the META-INF/context.xml for Tomcat and weblogic.xml for WebLogic. No worries, no changes.
What we did was create a folder structure for the properties that were environment specific. Under that folder we created folders for each specific environment targeted for deployment, including local development. It looked like this:
Project
\
-Properties
\
-Local (your PC)
-Dev (shared dev server)
-Test (pre-production)
-Prod (Production)
In each folder we put parallel copies of the properties/config files and put the different configurations only in the file in the appropriate folder. The secret was to control the classpath of the deployment environment. We defined a PROPERTIES classpath entry on every server. On Prod, it would be set to "$ProjectDir/Properties/Prod" while on Test the same variable would be set to "$ProjectDir/Properties/Test".
This way we could have database connection strings for the dev/test/prod database preconfigured and not have to checkout/in the property file each time we wanted to build for a different environment.
This also meant that we could deploy the exact same .war/.ear file to Test and Prod without rebuilding. Any properties that weren't declared in the properties file we handled in a similar way by using the same JNDI name in each environment but using values that were specific to that environment.
http://www.gifnoc.com/config could help as it stores configuration on a central place and the client is pulling from it for different environments

Categories

Resources