How to load application.properties file in another path? - java

I have a spring boot web app but I want to load the application.properties file in another path because it has private information about database connection string.
Here are things what I did:
Remove the application.properties file in the default path like this:
src
main
resources
application.properties
I tried a kind of command line (I use gradle not maven):
> gradle clean assemble
> java -jar -Dspring.config.location=<Insert the path here> build/libs/<jar-file>
As usual. The code would run with the configuration of application.properties file as my desire. But many changes later seems doesn't save and still run old code before it has changed. How to solve it?

You can try find the answer here.
Try to use other profile configure file and override what you need within.
Or if there are just a few things to change, you can override them without properties file. For example:
./gradlew run --args='--server.port=8080'
or
java -jar -Dserver.port=8080 app.jar

Related

FileNotFoundException in SpringBoot when running in Docker Container

My Springboot Application is running fine in IDE but when I create fat jar file and run on docker it gives the error. I am connecting my application with firebase so i want to include the serviceAccountKey.json file from the resource folder. The application runs fine in my ide, but while deploying it over the docker container it gives the error of file not found. Though when include the file and print it path it doesn't give any sort of error . But when i give the file path to fileInputStream it produces the error. I have tried multiple ways but nothing seems to work. I'm including the file using classLoader.getResource("filename.json").
I tried to skip the inclusion of file and do it by saving files content in a string and then sending it to stream but this method crashes the server whenever i query firebase.
this is the code where error is occurring. Notice that I'm printing the file path and it gets printed in the output before showing error. I have also tried file.getAbsoluteFile instead of path but doesn't work. Probably I'm doing it wrong or probably i have to mention the path in some other place as well which i don't know about. If anyone has done this before then please help me on this.
File path is getting printed but FileStream can't get it
An alternative to having a credential in a json file that is packaged with the application, would be that you set an environment variable upon starting the application, and instead load the key via application.yml. This way, you don't need to package the secrets into the application jar file.
1. create config class
#Configuration
#ConfigurationProperties(value = "my-custom-config")
public class MyConfig {
private String serviceAccountKey;
// getters/setters etc. if not using lombok
}
2. use above config
in other spring beans by injecting the config class, and retrieve the secret with getter, e.g. config.getServiceAccountKey();
3. Add config to your application.yml file
# application.yml
my-custom-config:
serviceAccountKey: ${ENV_VARIABLE_NAME} # <---- this way you can bind an env variable to your config.
4. Define env variable in container on startup
On instantiating the docker container, provide env option and define an environment variable.
docker run -env ENV_VARIABLE_NAME=<value> ...

How can I dynamically use externalized properties file with Spring jar?

With this setup (from Eclipse using Windows10)
I was able to correctly start my SpringBoot application. This one worked too (same directory pattern):
Now I'm packaging my project as JAR and I want to use an external properties file. I had an teste32.yml file beside my JAR at the same directory (also tried to use it inside /config directory, as show here, but it didn't work either)
I want to dynamically use a properties file beside my JAR file everytime. Doesn't matter at which directory they are, I wanted to dynamically point to a properties file always at the same directory as the JAR is. I want to say to my client: "take this JAR and this file, put them wherever you want and run this command X and everything will be alright". I'm trying to discover command X but before I add some dynamic path, I'm trying with absolutes paths. I'm using this:
java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target\
I manually copied teste32 inside target\ to test this. But this didn't work. This didn't work either (only spring.config.location variants):
-Dspring.config.location=file:C:\workspace\myProject\target\
-Dspring.config.location=classpath:/
-Dspring.config.location=file:C:/workspace/myProject/target/
I also tried with no spring.config.location, only name
So my questions are:
What does classpath: and file: mean? Until now I got the 2 correct setups by pure luck and I would like to understand when to use them.
When I have my project package as a JAR, what classpath becomes?
Finally, which combination is necessary to dynamically use a properties always at the same directory as the JAR?
UPDATE
Using --debug at the correct example got me this line at the very begging (Spring banner was still visible):
2018-09-25 15:45:14.480 DEBUG 11360 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'file:src/main/resources/xirulei/teste32.yml' (file:src/main/resources/xirulei/teste32.yml)
But after moving myJar.jar and teste32.yml to a specific directory and running java -jar myJar.jar -Dspring.config.name=teste32 --debug (without spring.config.location, since teste32 is at the same directory as JAR), I simply didn't get any ConfigFileApplicationListener debug line.
a) java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target
Did you check content of target dir? I'm pretty sure your cfg file is placed to target\classes\xirulei and it is why Spring cannot find it in target
b) When you place teste32.yml in the same directory as jar file then Spring must be able to find it (given this directory is working directory) without -Dspring.config.location (but you still need to provide -Dspring.config.name=teste32)
c) When you use -jar and do not provide additional class paths then classpath: points to the root of packages inside jar. Spring cannot find your file at classpath:/ because your file is at classpath:/xirulei/
Well, after all it was a simple mistake. As documentation says and as already pointed here, it should be
java -jar myproject.jar --spring.config.name=myproject
and not
java - jar myproject.jar -Dspring.config.name=myproject
As stated on question, only when using Eclipse -D(JVM argument) is necessary. When using bash/cmd, just --(program argument) is the correct option:

Set classpath for playframework

I am running a project using $ activator "run 8081". In the application, I try to read an xml file using the following command:
resource = ClassLoader.getSystemClassLoader().getResource(filePath)
The problem is that the resource is null. After debuging, I noticed that the running ClassLoader.getSystemClassLoader().getURLs() returns a single jar file. Which means that the above code is trying to load filePath from inside this jar file.
Any ideas on what I can do to fix this problem and load the filePath? Note that I have to keep the ClassLoader.getSystemClassLoader().getResource(filePath) as is, but I can change the value of filePath and environment variables, etc.
EDIT:
How do I set the classpath for activator when I run it in dev mode: $ activator "run 8081"?
Answering this can help answer my original question.

Spring boot external properties file in "current directory" is ignored

from the manual:
24.3 Application property files SpringApplication will load properties from application.properties files in the following locations and add
them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
It mentions current directory twice but this really doesn't mean anything:
I tried putting it in the root of my project (i.e. above src in the folder that matches the output of java.io.File( "." ).getCanonicalPath() and System.getProperty("user.dir");), and I tried putting it with the war files (i.e. in build\libs)
But the only place to put it that actually works is the default location (src\main\resources).
So what does "current directory" even mean and where do the files really go?
I need to find the correct external location for the files so I don't have to build database credentials into the app.
The guides say that putting application.properties in current directory will work and I found the exact current directory to put it in but it still doesn't work, which I can verify by the output of: System.out.println(System.getProperty("spring.datasource.url")); which is null It does output the correct value only with an embedded properties file.
According to ConfigFileApplicationListener:
// Note the order is from least to most specific (last one wins)
private static final String DEFAULT_SEARCH_LOCATIONS =
"classpath:/,classpath:/config/,file:./,file:./config/";
file:./ resolve to the working directory where you start the java process.
I agree with Stephane Nicoll's argument that we generally don't need this for development and test but needed for production where properties file is generally externalized and the one present in source code is not used. This is what works for me ,
java -jar myjar.jar --spring.config.location=file:D:\\RunRC\\application.properties
Directory - D:\\RunRC - mentioned in above command is sample from my machine.
I keep using properties file of source code i.e. from \src\main\resources\ in development and test but in production , I comment out entries and if I am starting my jar or war from D:\\RunRC then I provide Current Directory as shown in above java command and keep properties file there.
Just doing - #PropertySource({ "application.properties"}) or #PropertySource({ "file:application.properties"}) doesn't pick it up from the directory where jar or war is kept.
For database credentials, I would suggest to use OS specific environment variables and use syntax similar to - #PropertySource({"file:${CONF_DIR}database.properties" }) where CONF_DIR is existing environment variable pointing to that directory.
Hope it helps !!
I understand that the current directory is the root directory of your project. However, you can change this with -Dspring.config.location=your/config/dir/.
Have a look at this post enter link description here
If you search for "current directory java", you'll end up here with this question. The intention is that if you put an application.properties in the same directory as the application, it will be picked up by default.
You will not use that feature in development or for test as you shouldn't rely on that feature. But when running your app in production, it might be handy to put environment-specific settings in a configuration file that sits next to the application itself.
Current directory refers to where we execute our jar. Creating an executable jar via Spring Boot maven plugin and placing application.properties just beside the jar file will work. An example :here

Add external properties file to classpath

My application is packaged into a jar file and is run with the regular "java -jar ..." command.
I have a properties file "myApp.properties" in the directory: /opt/myuser/resources
I want to add the /opt/myuser/resources directory to the classpath. I believe this is advantageous because when the properties files are on the classpath, I can access the properties files in my source code without specifying the full path to the properties files (/opt/myuser/resources/myApp.properties). This way I can keep a properties file with environment-specific properties separate from my application.
I've tried to set the classpath using instructions from Oracle (http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html under "Using the JDK tools' -classpath option") like this:
java -cp .:/opt/myuser/resources -jar myApp.jar
but I get an error that the properties file myApp.properties (referenced in the source code) cannot be opened:
Caused by: java.io.FileNotFoundException: class path resource [myApp.properties] cannot be opened because it does not exist
Am I going about this the wrong way? Should I edit the classpath in another way?
Hopefully this will help someone else.
I've used as program arguments for spring boot
--spring.config.location=file:/opt/myuser/resources/myApp.properties
and then it will use that file.
pass this parameter in VM options/environment variables
-Dspring.config.location=/deployments/tomcat/instance-conf/myApp.properties
use gerResource solutions to load file on your Properties Object:
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
Class.getResourceAsStream ("/some/pkg/resource.properties");
ResourceBundle.getBundle ("some.pkg.resource");

Categories

Resources