#PropertySource cannot find classpath: - spring-boot

I am getting the following error:
Caused by: java.io.FileNotFoundException: class path resource [request-
ws/src/main/resources/application.yml] cannot be opened because it does
not exist
Class with the issue:
#Configuration
#PropertySource("classpath:request-ws/src/main/resources/application.yml")
public class RequestDataSource {
Now I am trying to access the yml file in from a different module. The module name is request-ws. The goal to to create two data sources. Any advice would be greatly appreciated.

The classpath for application.yml should be under: src/main/resources
according to: classpath:request-ws/src/main/resources/application.yml
you obviously don't have that yml file under:
src/main/resources/request-ws/src/main/resources/application.yml
Try to create your custom folder under: src/main/resources

Since my project is broken down into modules when the war file is made my application.yml file ends up in WEB-INF Put this on on your class:
#Configuration
#EnableConfigurationProperties
#PropertySource("classpath:WEB-INF/classes/application.yml")
public class DataSourceConfig {

Related

Give external path in #Value Spring annotation and Resource

In spring boot application how do I give an external windows path using #Value Spring annotation and Resource
The below example works fine that look into resources folder but I want to give the path outside of application like c:\data\sample2.csv
#Value("classPath:/sample2.csv")
private Resource inputResource;
...
#Bean
public FlatFileItemReader<Employee> reader() {
FlatFileItemReader<Employee> itemReader = new FlatFileItemReader<Employee>();
itemReader.setLineMapper(lineMapper());
itemReader.setLinesToSkip(1);
itemReader.setResource(inputResource);
and if I want to get the value from properties file in annotaion, whats the format to put the path in windows?
i tried these, none of them worked:
in code
#Value("${inputfile}")
in properties file:
inputfile="C:\Users\termine\dev\sample2.csv"
inputfile="\\C:\\Users\\termine\\dev\\sample2.csv"
inputfile="C:/Users/termine/dev/sample2.csv"
inputfile="file:\\C:\Users\termine\dev\sample2.csv"
inputfile="file://C://Users//termine///dev//sample2.csv"
When you use classpath spring will try to search with the classpath even if you provide the outside file path.
so instead of using classpath: you can use file:
Ex.
#Value("file:/sample2.csv") //provide full file path if any
Use the key spring.config.location in properties to set the config location. Spring-boot will by default load properties from the locations, with precedence like below :
A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root
and apart from this when you start the jar or in application.properties you can provide the location of the config file like :
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
You can serve static files from the local disk, by making the resource(s) "sample2.csv" as a static resource. An easy way to do this is by adding spring.resources.static-locations configuration to your applicaiton.properties file. Example:
spring.resources.static-locations=file:///C:/Temp/whatever/path/sample2.csv",classpath:/static-files, classpath:/more-static-resource
When I did this in one of the projects, I was able to access the file form the browser using localhost:8080/sample2.csv.

#Import fails to aggregate annotated config from dependent jar

I have a project setup where a common module (JPA.jar) containing Spring JPA configuration.
#Configuration
#EnableJpaRepositories({"com.db.jpa.repository"})
#EnableTransactionManagement
public class Jpa {
// ...
}
I intend to invoke the config from a webservice (spring boot) and have a config importing the JPA configuration from JPA.jar.
#Configuration
#Import(com.db.config.Jpa.class)
public class JpaApp {
}
This fails with following error:
Caused by: java.io.FileNotFoundException: class path resource [com/db/config/Jpa.class] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:51)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:88)
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:75)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81)
at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:731)
at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getRelated(ConfigurationClassParser.java:1007)
at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getAnnotationAttributes(ConfigurationClassParser.java:988)
at org.springframework.context.annotation.ConfigurationClassParser.collectImports(ConfigurationClassParser.java:536)
at org.springframework.context.annotation.ConfigurationClassParser.getImports(ConfigurationClassParser.java:509)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:300)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:635)
... 40 more
Unable to find any documentation that says this is illegal for Spring's #Import. However I see this is done for resources with #ImportResource, using a classpath prefix.
I can include a set of configs for each webservice component using the common JPA models and repos, but just wondering if aggregating #Configuration(s) specifically using #Import from dependency jars is possible.
Is it possible?
If illegal, is there any rationale to it.
Thanks in advance.
You can use #Import for configuration classes from other jars. I think that you are getting this error because your jar is not defined as dependency in your pom.xml (if you use maven of course), that's why Spring can't find it.

Read both internal and external property file using Spring boot

I have a spring boot application jar
#SpringBootApplication
#EnableScheduling
#PropertySource({"classpath:1.properties","classpath:2.properties"})
public class MyClass {
//My class
}
1.properties is in src/main/resources
2.properties is in server location project location
| MyClass.jar
| config
| 2.properties
But I am getting file not found for 2.properties when starting the application.Please let me know what I could be missing here.
Like mentioned in the comment, your 2.properties file is not under your classpath. You can only use classpath if your file really exists in your jar or war.
To get the 2.properties you should use the command file: instead of classpath:.
#PropertySource("classpath:1.properties","file:${application_home}2.properties")
I am not quite sure if its still necessary to have an OS environment variable or a system property to set the path to your property file. In this case I named it application_home.

How to know the classpath?

I want to read properties file keys and I found that there is the classpath attribute to set in the #PropertySource annotation :
#Configuration
#PropertySources({
#PropertySource("classpath:config.properties"),
#PropertySource("classpath:db.properties")
})
public class AppConfig {
//...
}
Where should the properties file be placed and how to know the classpath in the annotation ?
What is class path ?
The class path is the path that the Java runtime environment searches for classes and other resource files.
How to identify classpath ?
Check your IDE, what all in build path. Folders in Build Path are in classpath.
You can add any number of folders and files in classpath explicitly.
You can access anything within folders/packages of classpath can be accessed relatively :)
Classpath
Refer
You have two options
Define shared.loader in your /conf/catalina.properties. Example:
shared.loader = D:\data\properties
If you are using maven, put your properties in /src/main/resources
I found the location in this tuto.

Loading properties file WebSphere Liberty

I have a simple application that uses Spring to load a properties file from the classpath. When deploying this application to WebSphere Liberty 8.5.5 it results in FileNotFoundException.
nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/myprops.properties]
Here is my spring #Configuration class:
#Configuration
#Profile("dev")
#PropertySource("classpath:/myprops.properties")
public class AppConfigDev extends AppConfig {
...
}
I am wondering where in the Liberty directory structure should my properties file reside?
The use of prefix classpath: in your annotation signifies that the given property file would be picked up from WebSphere's, well, classpath, via a ClassLoader.getResources(...) call.
Ref: http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/resources.html#resources-classpath-wildcards
You will need to create a jar of all your properties files for Websphere Liberty to be able to load them.
Ref:
1. https://developer.ibm.com/answers/questions/13384/websphere-liberty-8-5-setting-java-classpath.html
2. Websphere Liberty 8.5: Setting Java classpath
You can set the name/directory of your files in a file named jvm.options and put it in your ${server.config.dir}/jvm.options
Specific example :
In the file: ${server.config.dir}/jvm.options
Add the following line: -DAPP_ENV=PROD
Access the value with: System.getProperty("APP_ENV"); -> PROD

Resources