Spring not able to find classpath resource with #PropertySource - java

I am using #PropertySource in my datasource configuration file to get property files located on classpath. Below is my project structure.
I believe I can do it in two ways:
By creating a package in src folder and add them there. As src folder is already included in the classpath in eclipse, following should work.
#PropertySources({
#PropertySource("classpath: com/spring/property/general.properties"),
#PropertySource("classpath: com/spring/property/hibernate.properties")
})
Second way is to create a resources folder and add it to the classpath and following should work
#PropertySources({
#PropertySource("classpath: general.properties"),
#PropertySource("classpath: hibernate.properties")
})
In my case neither of the two is working. Being an intermediate java developer this still confuses me. Can anybody guide me in the right direction. And also how we can configure classpath resources for Spring in a production environment.
EDIT:
I have changed my project structure to include properties file in src/java/resources and I can see the resources folder in build path. Still .properties are not found by spring.

For anybody facing problem with usign .properties files in Spring 4+, look at the thread below to match your setup with that of OP. Setup is all good except for a whitespace in configuration.
Not able to inject .properties file into Spring MVC 4.3 using #PropertySource

Related

How to springboot custom configuration file path?

Since my project has multiple environments and multiple small project groups, I need to handle the corresponding business logic according to different property names, but I can't find any parameter in bootstrap.yml that can set the custom configuration file path.
After I googled, I only found a way to modify the path of the custom configuration file through the startup class
Is there any other better way for me to configure it? Please help me!
Spring Boot look for your externalized configuration file in four predetermined
locations :
in classpath root,
in the package /config in classpath,
in the current directory
in /config subdirectory of the current directory.
i think you want to load configuration file from /config folder.
You can programmatically tell Spring Boot to load your configuration files from
custom location as below :
ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(Application.class)
.properties("spring.config.name:application,conf",
"spring.config.location:classpath:/your/location/of/config/folder,classpath:/another/location/of/congig/folder")
.build().run(args);

SpringBoot application with multiple application.properties running under Tomcat

I need two application.properties in my Spring Boot App.
I know that using the annotation #PropertySource I can specify more than 1 property files.
I tried to use: #PropertySource({"classpath:application.properties","classpath:external.properties"})
The idea of it is having application.properties with the machine independent properties and this file will be included inside the war file.
The other file (external.properties), will leave in the machine, and won't be included in the war file. Here I want to leave properties like the database connection and so on.
I've already changed catalina.properties for adding the external.properties location into the classpath, but unfortunately when running on Eclipse it doesn't work (complains about the missing database properties.).
If the external properties file will be available in a known location on the machine, then have an environment variable, system property, or command-line argument set up with the path to the file. Then, reference the file in you #PropertySource annotation using file: rather than classpath:
Example: #PropertySource("file:${CONF_DIR}/external.properties")
References:
Spring boot docs on external configuration
PropertySource documentation
Blog post regarding PropertySource

META-INF/spring.factories file missing from Spring Boot application

I am fairly new to Spring and Spring Boot, and was asked to work on a legacy Spring Boot project. I am supposed to include in the project some FailureAnalyzers provided by Spring Boot. According to tutorials I came across (like here), all that needs to be done is registering the several FailureAnalyzer classes in the META-INF/spring.factories file.
But when I build the project (using Maven), I don't see a spring.factories file inside the target/META-INF directory. I tried adding one myself but it doesn't seem to be read by the project. What am I missing? What should I be doing to register these FailureAnalyzers?
In case you need it, the spring.factories file looks like this:
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.AbstractInjectionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer
I think you have mistaken the location of spring.factories file. This file will not be present in the project resources folder. Go to Maven dependencies and look into each Jar META-INF file and you will find spring.factories file in most of the jars.

Persistence.xml file usage without container [packaging]

I am trying to use jpa/hibernate framework with a simple java console application without a container. According to jpa documentation the persistence.xml file should be placed under the folder META-INF on the src folder.
The issue came when trying to package the application as a simple jar file then the persitence.xml file will be within the jar file generated (since it should be placed on the src folder).
In this situation the persistence.xml file is not easy accessible to modify the application configuration like the DB URL, time out,the hibernate logs...
I tried to put the META-INF/persistence.xml outside the src folder and added it to the CLASSPATH but an error saying Could not find any META-INF/persistence.xml file in the classpath is always thrown.
Is there any way to keep the persistence.xml editable and accessible once the application is packaged and deployed on production like any other classic configuration file (eg .properties files).
Thank you
I think you don't need to make persistence.xml editable since you can provide additional properties when calling Persistence.createEntityManagerFactory() (or using similar Hibernate-specific mechanisms).
So, you can use persistence.xml for static configuration only, and configure dynamic properties using your own configuration mechanism.

Java: Accessing properties file inside a war

I already searched StackOverflow for "properties inside war", but none of the results worked for my case.
I am using Eclipse Galileo and GlassFish v3 to develop a set of web services. I am using a "dynamic web project" with the following structure
Src
-java_code_pkg_1
-java_code_pkg_2
-com.company.config
--configfile.properties WebContent
-META-INF
-WEB-INF
--log4jProperties
--web.xml
--applicationContext.xml
--app-servlet.xml
I want to access the "configfile.properties" inside one of the source files in "java_code_pkg1". I am using the Spring Framework and this file will be instantiated once the application starts on the server.
I have tried the following with no luck
getResourceAsStream("/com.company.config/configfile.properties");
getResourceAsStream("/com/company/config/configfile.properties");
getResourceAsStream("com/company/config/configfile.properties");
getResourceAsStream("/configfile.properties");
getResourceAsStream("configfile.properties");
getResourceBundle(..) didn't work either.
Is it possible to access a file when it's not under the WEB-INF/classes path? if so then how?
Properties props = new Properties();
props.load(this.getClass().getResourceAsStream("/com/company/config/file.properties"));
works when I'm in debug mode. I can see the values in the debugger, but I get a NullPointerException right after executing the "props.load" line and before going into the light below it.
That's a different issue. At least now I know this is the way to access the config file.
Thank you for your help.
If you are in a war, your classpath "current directory" is "WEB-INF/classes". Simply go up two levels.
getResourceAsStream("../../com/company/config/configfile.properties");
It is horrible but it works. At least, it works under tomcat, jboss and geronimo and It works today.
P.S. Your directory structure is not very clear. Perhaps it is:
getResourceAsStream("../../com.company.config/configfile.properties");
Check the location of the properties file in WAR file.
If it is in WEB-INF/classes directory under com/company/config directory
getResourceAsStream("com/company/config/configfile.properties") should work
or getResourceAsStream(" This should work if the config file is not under WEB-INF/classes directoy
Also try using getClass().getClassLoader().getResourceAsStream.
Are you sure the file is being included in your war file? A lot of times, the war build process will filter out non .class files.
What is the path once it is deployed to the server? It's possible to use Scanner to manually read in the resource. From a java file within a package, creating a new File("../applications/") will get you a file pointed at {glassfish install}\domains\{domain name}\applications. Maybe you could alter that file path to direct you to where you need to go?
Since you are using Spring, then use the Resource support in Spring to inject the properties files directly.
see http://static.springsource.org/spring/docs/3.0.x/reference/resources.html
Even if the class that requires the properties file is not Spring managed, you can still get access to the ApplicationContext and use it to load the resource
resource would be something like, classpath:settings.properties, presuming that your properties file got picked up by your build and dropped in the war file.
You can also inject directly, from the docs:
<property name="template" value="classpath:some/resource/path/myTemplate.txt">

Categories