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.
Related
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
I have a Maven/Spring boot project that I'm seeing some odd behavior in. To summarize, a spring profile is attempting to load, but that profile doesn't exist and isn't specified ANYWHERE in my code. It seems as if the profile name is being picked up from a different Java command line property though, which is why it is confusing me.
Essentially my command line looks something like this:
Java -DEnvironmentID=qa01 -jar myapp.jar com.something.package.Loader LOAD
From what I understand from Spring documentation's command line documentation is that I would need to call java with the -Dspring.profiles.active=profileName argument in order to invoke a profile. So while I'm NOT doing this, "qa01" is being picked as a profile and my application tries to load "application-qa01.properties"
During my testing, I've also noticed that small modifications to the "-DEnvironmentID" argument will prevent this from being picked up as a profile (ex. "qa10", "qa0", "a01", "qa100", etc...)
I'm stumped at this point and can't determine why it would be picked as a profile argument by Spring.
Just in case this could help someone in the future:
The problem was rooted in a dependency of my project. The dependency happened to use the same command line argument as my own to build out a path to the environment specific properties file packaged within the jar. The dependency project just happened to build out the properties file name/path just like a Spring profile, so it ended up not actually being related to profiles after all. When the dependency jar failed to provide the properties file, Spring continued to look for the file in my project, eventually throwing the error.
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.
I was thinking to use log4j for my standalone java project.
Is it possible to use it for java project(not a web app).
If its possible then how should I be able to initialize the properties file and where should
I put the properties file(directory structure).
Any help is appreciated.
Yes, it is possible, we do it all the time. You just need a log4j.properties file on your classpath, which in most cases means in the base directory of your jar file. If you wish to have multiple properties files with differing configurations, you can create a properties configurator in some entry point before your first logging statement.
Yes it's possible.
If you're planning to create a jar file.
Make sure that your log4j.properties is found in your classes folder in jar file.
Make sure that your log4j jar is included in your classpath.
Enjoy!
It's definitly possible to use log4j in a standalone project. Just set your classpath to include the log4j jar. As for the properties file, the apache documentation should say where to log4j looks for it (it's probably also configurable).
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