Externalizing properties files in spring boot - java

I am trying to externalize the properties file of my project.
Steps to run:
Created a jar file without properties file.
Run these script file from command prompt.
.
java -jar read-apis.jar --spring.config.location=classpath:..\config\application.properties,classpath:..\config\sql-config.properties,classpath:..\config\error-config.properties,classpath:..\config\messgae-config.properties,classpath:..\config\validation-config.properties
OR
java -cp ..\config\application.properties, -cp ..\config\sql-config.properties, -cp ..\config\error-config.properties, -cp ..\config\messgae-config.properties, -cp ..\config\validation-config.properties -jar read-apis.jar
Its not working for me please help me.

I am basing information from the Spring Boot documentation here and my own experience. From what I can tell you have a configuration directory at ../config. You can either:
Put the config directory at the location where you run the application from. If the config directory is located at . instead of .. it will be picked up without any additional parameters.
OR leave it there and use something similar to your first form like this: "spring.config.location=file:..\config\application.properties". Since it is not in the jar you will need to use "file" instead of "classpath".
Give that a try and see if it works. It looks like you are trying to put multiple files in the search list. It may work but I am not certain. If that is the case then the first bullet above may not work since only application.properties would be searched for in the config directory. You could always add the other files in using the config property since it looks like it always uses the default paths also.

java -Dspring.config.location=application.properties,sql-config.properties,error-config.properties -jar read-api.jar
This works out for me.

Related

Override ClassPath in Bash script to run Java application

I am trying to run a simple Java application in Unix. My Java application read a config file from a directory at run-time. I placed the files in /tmp/paddy/. I created a simple bash script to run a application.
I tried like below and it gives me "no main manifest attribute, in app.jar" error
#!/bin/bash
java -cp ".:./config/*.*" -jar "app.jar" com.test.MainClass
And tried with below command This time my application is running but couldnt find the aconfig file so it throw me NullPointerException - (since it couldnt load the config file)
#!/bin/bash
java -cp app.jar com.test.MainClass
What is the correct way to override classpath in Java -cp command ? I was searching over the internet, but couldnt get any good answers. I dont have any issues running in windows. Only in linux and I am pretty new to the linux environment.
You have four separate issues here.
-jar and -cp don't work together
If you use the -jar switch, the classpath is taken from the Class-Path manifest entry in the jar's manifest, and that is all that will happen - the -cp switch (and the CLASSPATH environment variable) are completely ignored. The solution is to fix your jarfile, which ought to have that classpath entry.
That's not how bash works.
Separate from that issue, your -cp parameter is broken.
*.* in.. linux...? That's late 90s DOS, mate!
It's java doing the parsing of that *, which is unique, because in linux it's normally bash doing it, but that doesn't work here, because bash will be adding spaces, and java needs colons/semicolons, which is why java does it itself. The point is, java is rather limited and only understands a single *. Which bash will mess up. So, there is really only one way to do this.
Single quotes.
One star.
For example:
java -cp '.:./config/*' com.test.MainClass
You don't seem to understand how classpaths work
Each individual entry in a classpath must be either:
A directory which contains classfiles.
A jar file
Note how it specifically cannot be 'a directory that contains jar files', and also cannot be 'a class file'; that is not a thing. The * is the usual treatment: It takes every file in the directory you padded with /* and considers them all to be part of the classpath.
So, if you write: java -cp ., that will not include app.jar. If you write java -cp './config/*', that will not include any class or config files hanging off of ./config (only jar files located there).
That's not how config files work
Including config files on the classpath is not how its done. You can, of course. This doesn't do anything whatsoever, unless you are using SomeClass.class.getResource or some other variant of getResource (those are no good, you should be using SomeClass.class.getResource or SomeClass.class.getResourceAsStream, but I digress), in which case, don't do that. Those aren't intended for config files, those are for static files (files that never change, such as, say, a 'save to cloud' icon for your swing user interface application). If you are doing that, you'd need to include ./config (and not './config/*') in your classpath, but it would be a better idea to fix your code.
config files should be in the user's home directory - System.getProperty("user.home"). You should consider the directory that contains the jar file(s) as the place where the executables live, and those are not necessarily editable by the user, and surely the point of a config file is that you can edit them. Hence why using the classpath for these is not how it is done.

How to override internal configuration file in Spring Correctly?

I have an internal application.yml configuration file located in the resources folder on classpath.
I have an external configuration file: /home/username/config.properties which overrides some fields to run in a server context.
I want the fields in the external config file to override internal file and retain the fields in the internal file if not defined in external file.
The answers suggested Spring - how to override internal config file with external file doesn't work.
For example, the following command doesn't works for me:
java -jar application.jar --spring.config.location=classpath:/,file:///home/minister/config.properties
How do I achieve this desired outcome?
EDIT: This issue only happens on Linux. When I run it with the overriden configuration file on my Windows 10 machine, it works properly.
Looks like you have one too many /, try:
java -jar application.jar --spring.config.location=classpath:/,file:/home/minister/config.properties
You can pass the path to file, relative to the .jar file, for example,
java -jar application.jar -Dspring.config.location=./config/application.properties
or
java -jar application.jar -Dspring.config.location=../common/config
either of these work. Please refer - Spring Documentation for further details on how externalized configuration works.
Hope this helps.

Run JAVA war file from command line with classpath to start API

I'm having big problems running my java api war file from the command line after ive packaged it with maven.
I'm trying to run it using the following command from the target folder where my war file is located.
java -cp silverkissen.war se/consys/silverkissen/heroku/Main
And alot of other variations but i just get
Error: Can't find or load main class se/consys/silverkissen/heroku/Main
My war file lies in path ..\Silverkissen-API\target\silverkissen.war
My heroku main class lies in path ..\Silverkissen-API\target\classes\se\consys\silverkissen\heroku\Main.class
Thankful for any help.
The main issue is most likely because the class files isn't incorporated into the silverkissen.war file. Meaning there is no Main function in the war file itself. Or that the entry function is some where else.
Or that it's packaged in some mysterious way that is beyond my understanding that's specific to maven, heroku etc.
But assuming you're standing in the project root structure, one level before the target folder usually where you'd normally have src, target, pom.xml and system.properties. I'd try running the following:
java -cp target/classes:target/dependency/* se.consys.silverkissen.heroku.Main
And if you're on Windows that'd be:
java -cp target\classes;target\dependency\* se.consys.silverkissen.heroku.Main
That aught to do it. This will execute your project with class-path's in the runtime. Assuming my limited knowledge of Java is correct.
Someone with more experience can probably explain in detail why this would work.
Open command prompt in the location where your jar/war located
And then run below command
java -jar silverkissen.war

Setting log4j properties file via JVM argument - why does order matter?

I have built a jar file which has a log4j.properties file in it (mvn package put it there by default from the resources directory). But when I run this jar file, I want to pass a different logging config, so I add -Dlog4j.configuration=file:{path to file}. The issue that bugs me is that the order matters here as follows:
When I run java -jar {path to jar} -Dlog4j.configuration=file:{path to file} then it reads the log file packaged in the jar.
When I run java -Dlog4j.configuration=file:{path to file} -jar {path to jar}, then it reads the config from the file I pass in the parameters.
I have rough understanding how classpaths work in java and that if I were to load several java classes with the same name, it would make a difference. But this way I am passing a config parameter with a -D prefix, so the way I expect this to work is for some code in log4j library to check whether -Dlog4j.configuration is set and if so, then load the config from there, otherwise try to find it on the classpath.
Any ideas on what I am missing?
If you provide anything after naming the JAR file, it is treated as an argument to your main method. For Log4J you actually have to define a property, and this needs to be done before you specify -jar.

How to execute Hadoop Jar with external properties

I have a jar application that works with an external properties file. The file is used so that the user can override default properties. The default and core properties are part of the build so no problem there.
Normaly I would do something like one of theese:
java -jar MyAwesomeApp.jar user.properties
OR
java -jar MyAwesomeApp.jar -Dmyapp.userproperties=user.properties
But with hadoop, the jar gets executed inside the hadoop framework like this
/bin/hadoop jar MyAwesomeApp.jar input output
And no matter where I put the -D I can't get the value via System.getProperty(...). The properties is not set. The hadoop documentation said that -D is a GENERIC OPTION and is set after the command. But if I do so I get an error that -D is not a valid jar file (duh...)
I aim to keep the application as clean as possible...so I only want to pass the user configuration as a parameter as a last resort, i.e.
/bin/hadoop jar MyAwesomeApp.jar input output user.properties
I hope someone can tell me what I have to do to get the -D working :/
Hadoop is running pseudo distributed so I am actually using HDFS too...

Categories

Resources