Spring: Configure PropertyPlaceHolder when Property File outside Jar File - java

I have a SPRING 2.5.6 based project and my properties file is outside executable Jar file like
./
|---MyApplication.Jar
|---MyApplication.properties
I don't know how to configure PropertyPlaceholderConfigurer so that it can pick the file outise of JAR file or any other way by which spring can know the location of properties file. In other words How to put Jar root path in class-path because spring can automatically pick the properties file from class-path.
I have read the following Questions but it did not exactly tell how to configure PropertyPlaceholderConfigurer.
Read properties file outside JAR file
Add properties file to build path of runnable jar
java -jar -cp . ./main.jar
I know this way of adding root path into class-path but my client do not want to run jar by command line or batch file. So is there a way to configure Spring somehow?
I think of possible solution is to make JAVA base configuration alongside xml base configuration.

java -jar -cp . ./main.jar
Change run command.

Solution- To get the directory where jar is located, spel can be used.
The following should get you going.
<context:property-placeholder location="file:///#{T(java.lang.Object. getClass().getProtectionDomain().getCodeSource().getLocation‌​())}/ application.properties"/>

You can use Maven or Gradle to manage your project, he can help you automatically add dependencies, you do not need to manually import Jar package.

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.

Run spring boot jar file with profiles - error can't find properties files

I am facing problem in running a spring boot jar file with external profile.
I have a spring boot project with jersey. I have placed the properties and some certificate file in different directories (for different servers development and production etc). The application needs these properties and certificate files.
My project structure looks like
MyProject
|_configurations
|_local
|_dev
|_web
|__src
|_target
I can run it locally on intelliJ by by setting the local profile in class path.
I am generating the jar file out of the web directory.
When I run the jar file it complains and can not find the properties and certificate files.
These are my attempts
Generate a new jar file by placing the required properties and certificates in resource
directory under web\src\main directory.
Putting the properties file in class path while running the jar file as
java –jar –DApp.config.file="c:\MyProject\conf\local" MyProject.jar
But nothing works and i get the same error, complaining that properties and certificate files could not be found.
Any help how this can be solved. Is there any other better solution to solve this kind of problem.
Finally i figured out how we can work with the profiles.
If the configuration files are inside the project
Load the profile in class path by name of the profile while running the jar
java -jar -Dspring.profiles.active=<Profile name> YourApp.jar
the following If the configurations are outside the jar file
Load the profile and configuration while running the jar
java -jar -Dspring.profiles.active=<profile name> -Dloader.path=file:///C:/yourdirectorypath/MyApp/conf/environments/local MyApp.jar
Also note that the order should be same as in given command i.e. Profile > Dloader.path > jar file name

log4j likes its properties in a jar file?

I have a Java application which I'm executing on Linux direct from an executable jar file
java -cp .:./lib -Duser.timezone=GMT -Dlog4j.debug -jar programName.jar
The program uses a number of other jar files which are all in one directory and 4 properties files all of which are in another directory (the current directory). Both directories are included in the CLASSPATH.
Simple enough right.
It would be, except that Log4j fails to find log4j.properties. The only way I have managed to make it find log4j.properties is to include it in programName.jar
This is not what I want, I want to have it using log4j.properties residing in the same directory as all the other properties files, they are in the CLASSPATH and are found as you would expect.
The other jar files being used are:
jdom-2.0.5.jar
log4j-1.2.17.jar
ojdbc7.jar
quartz-2.2.1.jar
slf4j-api-1.7.7.jar
slf4j-log4j12-1.7.7.jar
I'm wondering if slf4j-log4j12-1.7.7.jar does some configuration which prevents log4j from scanning the CLASSPATH when looking for the properties file. My code does not include any instructions which aim to specify the location of the properties file.
I've not yet tried executing the program without the -jar option, I will try that next.
Does this ring any bells so far ?
Add an argument to jvm (log4j.configuration). e.g.:
java -cp .:./lib -Dlog4j.configuration=file:log4j.properties -Duser.timezone=GMT ...
You may want to see this answer for more options.

how to write Java Code to let JPA/hibernate know where to look for Configuration files?

I'm a newbie to JPA, hibernate and Java itself.
I have somehow made my code work to access values from a DB.
When I extract my final jar of jars, I have a META-INF directory which has persistence.xml in it.
The hibernate.properties and hibernate.cfg.xml are also inside my jar.
So at runtime I'm unable to do any changes to these files since everything is inside jar.
I want to move persistence.xml, hibernate.cfg.xml and hibernate.properties outside jar and place them somewhere in deployment environment. I can do this but I don't know how to write Java Code to let hibernate know where to look for these files.
E.g. for log4j I can use PropertyConfigurator.configure("/opt/somepath/log4j.properties") and tell log4j where log4j.properties file is present.
Could anyone please help me and direct me to some links where I can learn to load configuration for JPA and hibernate at runtime ?
I want to point to different DBs at runtime and test them without changing my jar of jars.
jpa/hibernate scans classpath where looking for configuration files. You can always add to classpath directory/directories.
MY_DIR1 = path/to/my/dir1
My_DIR2 = /path/to/my/dir2
java -cp ${CLASSPATH}:${MY_DIR1}:${MY_DIR2} ...
Put META-INF directory to ${MY_DIR1} ( or/and ${MY_DIR2})
With the help of ajozwik Answer I solved my problem as follows ->
Created a /path/to/mydir directory at some place in my deployement system.
Moved META-INF and hibernate.properties and hibernate.cfg.xml to mydir.
Directory Structure->
mydir
META-INF
persistence.xml
hibernate.properties
hibernate.cfg.xml
Added mydir to class path while launching the executable.
Instead of launching the executable using
java -jar Myjar.jar
I launched it using
java -cp Myjar.jar:/path/to/mydir MyMainClass

disabling log4j in the common jar file

I have problem with log4j.xml. I am using one common jar in my standalone application. The commom jar has its own log4j.xml file. The problem is my Unix server is not having the file structure specified in the common jar log4j.xml file so i am getting file not found error , when it tries to create log file.
I have tried to override the log4j.xml file by writing a new log4j.xml file in my application. But still common jar is using its own log4j configuration. I am running my Application using a shell script. Can you please help in disabling or overriding log4 configuration in the common jar .either from java side or any shell script command.
Thank you.
Start the java application with -Dlog4j.configuration=com/foo/bar/log4j.xml in order to use a specific config file, overriding the one found in your jar, or make sure another log4j.xml is at the root of the classpath, before common.jar:
java -cp aDirectoryContainingLog4jXml;common.jar com.foo.bar.Main

Categories