I am drawing a blank on this for some reason. I have a multi-module Spring/Maven project. In module1 I define a singleton bean called "info" and it works within module1 just fine.
However module2 in this project (which depends on module1) has improvements on property values for the "info" bean. Module2's Spring configuration already includes Module1's configuration. What is the Spring configuration I should use to set properties on the "info" bean defined in this subsequent module?
Since Spring 2.5 there is a PropertyOverrideConfigurer. Maybe that's what you are searching for
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-overrideconfigurer
There is a small example on this page
http://ondra.zizka.cz/stranky/programovani/java/howto-substitutions_in_spring_configuration-tutorial.texy
Create a new "info" bean in module2, configuring it the way specific to the needs of module 2.
You would do something like this in your module 2 configuration:
<import resource="classpath:/META-INF/module1-config.xml"/>
<bean name="info" class="Module1class"/>
This should inject the right "info" into the dependent beans
Related
I have a main module named core and other modules that defines Spring beans of type Job.
I'd like to have a List<Job> in my main module.
The problem is that the creation of the #Service class that contains the #Autowired List<Jobs> is happening prior to the creation of the Jobs in the other modules (which are a maven dependency in core).
How can I direct Spring to gather all Jobs into a list in the main module?
I tried to use #Order but it doesn't seem to make any affect.
Try creating Job bean under configuration file.
I understand that the way these projects have been structured isn't necessarily good design, but i have found myself working on a project which has the following format and have a dependency and spring bean configuration issue:
Project A :
Is a Spring Project. Spring configuration is in an XML file. The project consists of many different beans and classes. Some of these classes are Services which make calls to a database(JPA/Hibernate is used). So in the Spring configuration file there is an entityManagerFactory defined, a Datasource etc and all the beans needed to perform database operations.
Project B:
Is also a Spring project, and also contains various beans and classes. This project also contains classes which make calls to a database(using JPA/Hibernate). So the Spring configuration also defined an entityManagerFactory/datasource etc. The project contains a series of Entity Classes which are scanned by the entityManagerFactory using the property 'packagesToScan'. The configuration is using Java Config.
The problem:
A bean in Project A needs to use a bean from Project B. The bean from project B is a Service class which reads data from the database. I want to be able to inject the bean from Project B into the class from Project A. I am using gradle in both projects, so have added Project B into Project A as a gradle dependency.
I tried adding a to the configuration from Project A to scan the package in Project B which contains the Java Config. I thought this would enable me to autowire the class from Project B into Project A. However, i am getting an exception that the entities in Project A are not managed entities and that autowiring is failing. Does this mean i need to scan the entities in Project B with the entityManager in Project A? Does this mean i cannot autowire a bean which has already been configured in the configuration of another project? Do i need to add this bean to Project A xml configuration and do all the property setting there, copied from Project B?
I'm having a problem properly setting up spring boot for my multi-module maven project.
There is a module "api" that uses another module "core". Api has an application.properties file that contains spring.mail.host=xxx. According to the spring boot documentation this provides you with a default implementation of the JavaMailSender interface, ready to be autowired.
However the class that is responsible for sending out the e-mails resides in the "core" package. When I try to build that module the build fails because no implementation of JavaMailSender can be found.
My guess then was that the mailing config should reside in "core" in a separate application.properties. I created that and moved the spring.mail.host property from the "api" to the "core" property file.
This time the core module builds successfully, but "api" fails to build because of the same exception, so I think I just moved the problem.
I don't understand the required structure for handling this type of situations well enough so I was wondering what the correct way is for having a "core" module containing all the correct configuration for sending mails and having other modules use the mailing code and config that resides in it.
I found the answer in another stack overflow question: How to add multiple application.properties files in spring-boot?
It turns out there can only be 1 application.properties file in the final jar that spring boot creates. To have multiple files you have to rename one of the files to something custom. I named the properties of the core module "core-application.properties".
Then in the API module I added this to the spring boot application class:
#SpringBootApplication
#PropertySource(value = {"core-application.properties", "application.properties"})
Doing this I can correctly use the base properties file and overwrite them in the more specific modules. Also you can still create profile-specific properties file (core-application-production.properties) with this setup, no need to add those to the propertysource manually). Note that #PropertySource does not work for yaml configuration files at this moment.
there is one effective application.properties per project. you just keep 2 properties file for a success build.
when api module use core module, the application.properties in core module is overwrite by api.
Your API's pom.xml must has dependency of CORE module.
the solution is to define properties files as a value of #PropertiesSource in Starter class.
but it is beter to put "classpath:" behind the properties files.
for example in Intellij idea after adding the "classpatch:" word berhind the files name, values become to link. like this:
#SpringBootApplication
#PropertySource(value = {"classpath:core-application.properties", "classpath:application.properties"})
I hope to helped you.
Goal:
List item
I have a spring webapp project, which is using component scan for configuration and autowiring interface implementation through maven submodules
the main project is dependant on the other modules thus the jar's of the submodules are placed in the /WEB-INF/lib folder
the submodules (aka plugins) have common package parent name x.y.z.extension eg. x.y.z.extension.pluginA
the classes in this package are annotated with #Component or #Configuration
in the servlet xml configuration i have placed such component-scan information:
Code:
<context:spring-configured />
<context:component-scan base-package="x.y.z.extension" />
With the mentioned configuration everything is working correctly.
What I would like to achieve:
List item
remove dependency of the main webapp maven module and other modules - the core webapp will be shipped without plugins
create subfolder e.g. "WEB-INF/classes/plugins" in the classpath classes dir
put there the mentioned jar's from submodules (or extract the jar content to eg. WEB-INF/classes/plugins/pluginA) - this could be done during "plugin installation" with webapp restart after new plugin installation
spring automagically should detect annotated classes and load it into the application context (and use not annotated classes in the plugin jar (annotated classes are mainly interface implementation but they are using some not annotated classes in the jar))
and ... of course this does not work The classes are not found.
If it possible to achieve this only using spring ecosystem, or should I take a look into other examples e.g. jspf ?
How can I modify classpath scanning with spring and also keep automatic component scanning ?
thanks !
I have a new web app that is packaged as a WAR as part of a multi-module Maven project. The applicationContext.xml for this WAR references beans that are imported from the "service" module, which in turn imports beans from the "dao" module. The import statement in applicationContext.xml looks like this:
<import resource="classpath*:service.xml" />
and the one inside the service.xml file looks like this:
<import resource="classpath*:dao.xml" />
Neither Spring STS, nor Eclipse show any warnings or errors in my bean files. I reference the imported beans all over the place. The Maven build works fine and the DAO integration tests all pass (they use the beans). I don't have any service integration tests yet.
But when I start up the WAR in Jetty I get an error:
Error creating bean with name 'securityService'
Cannot resolve reference to bean 'userDAO' while setting constructor argument
All of the imported bean XML files can be found inside their respective JAR files in the WEB-INF/lib directory. Indeed, the service bean that threw the error is itself defined inside the service.xml file inside the service module's JAR file.
Apparently the service module can't find the bean that it imported from the dao module. Obviously I don't understand something...seems like this should this Just Work?
I enabled DEBUG logging for 'org.springframework' in order to see if I could learn anything. What I found were messages to the effect that the DAO beans had been created, but there was also a message about them having no name or id.
I check the file, and they all did have an id. So what was it? I check the XML namespace and saw:
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
and noticed it was old (I am using Spring 3.0.2) and changed it to:
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
Once I changed it, Spring instantly threw half a dozen errors regarding beans that were defined incorrectly (but never used apparently). Once I fixed those errors, everything Just Worked. I've since gone through the entire system checking Spring XML file namespace versions.
Thanks to all for the help. Can't believe I wasted a day on this stupidity!!
The difference between the classpath:thingy.xml and classpath*:thingy.xml notation is that the former uses the standard classpath mechanism to resolve one resource (using ClassLoader.getResource(name)), whereas the latter will use ClassLoader.getResources(name) to retrieve all matching resources on the classpath, a distinction that should be irrelevant in your situation as I guess there is only one dao.xml file on the class path.
I think your problem is different, you are missing a leading slash.
Use this for a single resource
<import resource="classpath:/dao.xml" />
and this for multiple resources
<import resource="classpath*:/dao.xml" />
See
Spring Reference: The classpath*
prefix
Sun JavaDocs: ClassLoader
It should be like
<import resource="classpath:service.xml"/>
Are you having multiple applicationContexts and possibly the parent context is referring to a bean defined in the child context?