I have a Spring Boot application that runs properly when I run it from Intellij as maven configurations.
I have a project structure of environments that is defined with properties files.
resources/conf/dev/environment.properties
resources/conf/qa/environment.properties
resources/conf/general.properties
etc.
Our framework works in a way that we are choosing the env with VM arguments.
for example -Denv=dev or -Denv=qa
After packaging the App to an executable JAR and trying to run it, Spring Boot can't identify the properties files under conf path of the project.
When I look inside the JAR the properties files are under {jar-name}.jar\BOOT-INF\classes\conf.
The error is:
java.io.FileNotFoundException: conf\general.properties (The system cannot find the path specified)
2017-07-11 10:52:52.864 INFO 17896 --- [main] n.lifecycle: Can't find configuration file [conf\general.properties]
2017-07-11 10:52:52.865 ERROR 17896 --- [main] n.lifecycle: configuration file [null] not found (use default properties as error handling)
I've tried to work with the documentaion here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
but nothing seems to fix it.
Also tried to work with this guide - http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#executable-jar-launching but also failed...
The guides are referring to the properties files as "external" but my properties are packed in the JAR.
I've found out what's wrong.
Our in-house framework that's loading the resources are using File.separator to read the path of the resources.
Now for some reason when the jar is created with maven spring boot plugin the classpath is built with '/' for example /C:/Users/MyUser/Projects/MyApp/target/MyApp-1.0.1.jar!/BOOT-INF/classes!/ (the resources are in classes path inside of the jar of course)
And when we are trying to run the jar it's trying to read the resources with '\' so the path that is built is (if we choose "dev" for example) /C:/Users/MyUser/Projects/MyApp/target/MyApp-1.0.1.jar!/BOOT-INF/classes!/conf\dev and that is why the app is failing to load.
I still don't know why this is happening.
Try to put properties files in resources.
Not in resources / conf.
It works so well.
Related
How to override Java resources when you run Spring Boot fat-jar?
I've created a Spring Boot far-jar that contains inside as resource a log4j.xml configuration file. Now when I run the fat-jar I'm trying to override it in this way
$ java -cp conf/ -jar target/myapp.jar
and I've put in the conf/ folder a new log4j.xml. But nothing, it continues to use the resource inside the jar.
If your goal is only to define your own log4j.xml configuration file, this could help:
java -Dlogging.config='/path/to/log4j2.xml' -jar target/myapp.jar
(this was mentioned already in How can I change the default location of log4j2.xml in Java Spring Boot? )
If you just want to add resources by classpath addition you could refer to
https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-executable-jar-format.html#executable-jar-property-launcher-features
where I found loader.path :
loader.path can contain directories (which are scanned recursively for
jar and zip files), archive paths, a directory within an archive that
is scanned for jar files (for example, dependencies.jar!/lib), or
wildcard patterns (for the default JVM behavior). Archive paths can be
relative to loader.home or anywhere in the file system with a
jar:file: prefix.
I'm using Intellij.
I have a jndi.properties file (used for connecting to a Wildfly instance).
By default, Maven includes this file inside the JAR , after build. This is not good, as the jndi.properties contains the URL and credentials to the Wildfly instance and in production these will be different.
I managed to exclude the jndi.properties file by placing it in a separate folder (called config), and then in Intellij -> Module Settings -> Sources I marked the config folder as Resources and Excluded. This way, when I run the application inside Intellij, it works fine. But when I build the JAR, even if I place a folder called config outside the JAR, I still get an exception because no jndi.properties file is found in the classpath.
The same happens if I declare the config folder in the Dependencies tab in the Module Settings.
I also tried specifying the classpath when I run the java cmd line tool, but it seems that -cp does not work along with -jar.
I know two alternatives, but I don't really like them: have jndi.properties in JAVA_HOME/lib (not good, it will be common for all applications) or at runtime (-Djava.naming.provider.url etc, not as clear as a configuration file in my opinion).
Is there any way I could specify the jndi.properties file location at runtime?
I have Spring configured to look up a conf/database.properties file to load some configuration.
This works well outside Tomcat, and in Junit tests, but in Tomcat, it never load. Below the images of this problem.
Configurations:
And:
The properties file in project folder:
The parameters to run Tomcat inside Eclipse:
The temp0 Tomcat Folder, where is all the files being generated Ok:
The Tomcat error log:
https://gist.github.com/4060538
I solved the problem. I think I was using spring in the wrong way.
I changed the follow:
In the library I'm importing/referencing, I removed the line where was importing database.properties file.
I created a spring.xml in my main web app, where in this file I imported the database.properties file and the other app-context.xml files I need to reference.
I think Spring spring don't load properties file outside of the jar. You need to load properties file locally in you main application, and so, references another spring-context.xml files needed.
I don't want to put my .properties and log4j files in my /resources folder in my spring MVC appication because these will get put into the jar at compile time, and I want to be able to edit these files on my server when I deploy my application.
So I created a folder and dropped my log4j, *.properties files, and my spring-context.xml file in it.
I have a maven multi project, and my folders look like:
/myapp-persists
/myapp-web
/src/main/conf
The /src/main/conf has my property files, so in IntelliJ I went to the myapp-web module and added a 'jar or directories' dependancy, pointed to that folder and chose 'classes'.
It didn't work, my files were not picked up and starting the server resulted in a crash, the property files were not detected.
What am I doing wrong here?
It seems me doing this via intelliJ is going to cause my maven builds to fail then right? I really don't want to create a separate maven project for this.
You can just use the context menu on /src/main/conf and choose Directory : Add as Source. In the preferences you should set keep source folders in the maven settings (not really sure about the naming of the menu/settings - no idea at hand, sorry). The jar dependency is not needed.
I am working on a fairly big project that uses maven for dependency management. As part of this we are using Maven profiles to build and replace certain properties files that differ between test/dev/production environments.
To perform a build I would execute a Maven:build using the correct profile and mavens reactor would then build the projects in the correct order and store the jars in the .m2 folder, eg the domain jar first, then the service jar (with the domain jar included in its jar as a dependency) etc. This leads to a war file eventually with all the correct libs required by the war to run.
When eclipse performs its default build that it performs everytime you save a file the jars are not built with any profile, just a regular build.
When I then push the final war file to the server and it is exploded when the server starts up (started and deployed through eclipse) I get in the lib folder all the jars that maven had packaged into the war file but also all the jars that eclipse had built.
eg
lib/
domain.jar (built by eclipse)
domain.SNAPSHOT.1.0.jar (built by maven)
etc
Is there any way to prevent this from happening? This has the end consequence of there being two of every property file and only the order in which they are loaded determines which is used. A real hassle as different properties are used in different environments.
I found a slightly hacky solution to this problem.
In the web projects properties -> Deployment Assembly I modified the path for the offending jar files eg domain.jar from
WEB-INF/lib/domain.jar
to
WEB-INF/autogen/domain.jar
This leads to the eclipse generated jar files (with the wrong properties files) to be deployed to a folder that won't be loaded when tomcat starts. Not a perfect solution but it allows all the nice things of eclipse auto-building like code completion and error messages in the web project if the interface of the domain changes etc while also providing the correct profile when deployed.
Leaving this here for anyone else in this situation.