#Import fails to aggregate annotated config from dependent jar - spring

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.

Related

jar with embedded tomcat, when using another spring project, is not working with just yml - it's needing a blank application.properties file as well

Been searching for others that have run into this issue, and not finding much out there, so it can't be that common.
I have a spring-boot project that I want to convert into a jar project, running with embedded tomcat. It's using yml files (application.yml and then the profile versions - eg appplication-dev.yml.) It ran fine as war with the yml files, however, when I convert it to a jar, and kick off the jar, the embedded tomcat never starts UNLESSS I add an empty application.properties file as well. (No errors just no Tomcat startup unless the empty application.properties file is added.)
I believe it's somehow related to one of our internal jar dependencies (also spring), since if I remove that dependency from the pom (and any of the code referencing it) I can get the jar to startup the embedded tomcat just fine (without providing the empty application.properties file.)
I could also, of course, forgo using yml files and just use .properties files, but I'd like to use yml files if possible. Why adding an empty applcation.properties file causes things to work has me stumped.
If it helps, the config in the dependency project that causes the issue we're seeing is set up as:
#Configuration
#EnableConfigurationProperties(OracleDataSourceProperties.class)
#EnableTransactionManagement
#ComponentScan(basePackages = {"com.foo.data.services","com.foo.data.domain", "com.foo.utility", "com.foo.cipher.utility"})
#MapperScan(value = {"com.foo.data.services.mapper","com.foo.data.services.batchmapper"})
public class DataServicesPersistenceConfig { ... }
and the OracleDataSourceProperties class:
#ConfigurationProperties(prefix="oradb", ignoreUnknownFields = true)
public class OracleDataSourceProperties extends BaseVO implements InitializingBean{

spring boot jar file wont run

I have made an spring boot app and it works fine with maven but when I run it's jar file it gives an error like
java.lang.IllegalAccessException: class org.springframework.boot.loader.MainMethodRunner cannot access a member of class com.cafe2.user.UserApplication with modifiers "public static"
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
at java.base/java.lang.reflect.Method.invoke(Method.java:558)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
at java.base/java.lang.Thread.run(Thread.java:829)
i have not such an error when i am running app with maven
it was really stupid the error was because of public in boot class i just add public and it works –
public class UserApplication {

#PropertySource cannot find classpath:

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 {

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

In Spring, can I autowire a property value simply by including that JAR in my WAR file?

I’m using Spring 3.2.11.RELEASE. I have a JAR file with a class that has the following
#Service(“myService")
public class MyServiceImpl implements MyService
{
…
#Value(“#{myProperties[‘my.properties.key’]}”)
private String myPropertiesValue;
When I include the JAR file in a WAR, I must put this in the WAR’s application context or else the autowiring fails …
<util:properties id=“myProperties" location="classpath:my_file.properties" />
The file “my_file.properties” is at the root of my JAR file. My question is, is there any way I can get the autowiring of the property to occur by simply including my JAR file in my WAR? I realize that adding ‘<util:properties id=“myProperties" location="classpath:my_file.properties" />’ is not that hard, but when I include the above JAR in dozens of projects, it is easy to forget to include the “util” declaration in one or two, causing those applications to fail to deploy.
There is no other conceptually different way. Either you include the properties or you can import full xml which defines part of the application context specific to this jar:
<import resource="classpath:my_jar_config.xml" />
where my_jar_config.xml contains all beans and the <util:properties> specific to this jar.

Resources