When I try to load a resource, it never gets loaded and instead comes back as null. My code is as follows:
Controller.java
#Controller
#Path("/users")
public class UsersAPI {
#Resource(name = "dataLoaderList")
private List<DataLoader> dataLoaderList;
}
spring.xml
<context:component-scan base-package="com.my.package" />
<import resource="classpath:spring/commons.xml" />
<import resource="spring-dataloader.xml" />
<import resource="spring-security.xml" />
spring-dataloader.xml
<bean id="dataLoaderList"
class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<ref bean="dataLoader1" />
<ref bean="dataLoader2" />
<ref bean="dataLoader3" />
</list>
</property>
</bean>
What could I be missing?
EDIT:
I tried loading the resource in a JUnit Test, and it worked. So I have no idea why it wouldn't work in my Controller.
junit
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:spring/spring.xml")
#ActiveProfiles("dev")
public class Test {
#Resource(name = "dataLoaderList")
private List<DataLoader> dataLoaderList;
}
I had to change #Controller annotation to #Component and that fixed my error. I have no idea why it worked.
Related
I am quite new to Spring and Activiti. I'm developing annotation based Spring web application with embedded Activiti engine. I have some services implemented, SubscriptionService is one of them. In one process I call that service as bean with:
activiti:expression="${subscriptionService.getContacts(publisherCode, contactType)}"
Service:
#Service
#Transactional
public class DBSubscriptionService implements SubscriptionService {
...
}
I have separated test module and web module. Test module loads context from activiti.cfg.xml with
#ContextConfiguration("classpath:activiti.cfg.xml")
and it is:
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="databaseType" value="h2" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="history" value="full" />
<property name="mailServerPort" value="2025" />
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="repositoryService" factory-bean="processEngine"
factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine"
factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine"
factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine"
factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine"
factory-method="getManagementService" />
<bean id="identityService" factory-bean="processEngine"
factory-method="getIdentityService" />
<bean id="formService" factory-bean="processEngine"
factory-method="getFormService" />
<context:component-scan base-package="cz.muni.fi.cep" />
<context:annotation-config />
In test module, everything works fine. But in web module when it should call subscriptionService Bean it throws:
Unknown property used in expression: ${subscriptionService.getContacts(publisherCode, contactType)}
Caused by: org.activiti.engine.impl.javax.el.PropertyNotFoundException: Cannot resolve identifier 'subscriptionService'
at org.activiti.engine.impl.juel.AstIdentifier.eval(AstIdentifier.java:83)
at org.activiti.engine.impl.juel.AstMethod.invoke(AstMethod.java:79)
at org.activiti.engine.impl.juel.AstMethod.eval(AstMethod.java:75)
at org.activiti.engine.impl.juel.AstEval.eval(AstEval.java:50)
at org.activiti.engine.impl.juel.AstNode.getValue(AstNode.java:26)
at org.activiti.engine.impl.juel.TreeValueExpression.getValue(TreeValueExpression.java:114)
at org.activiti.engine.impl.delegate.ExpressionGetInvocation.invoke(ExpressionGetInvocation.java:33)
at org.activiti.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:37)
at org.activiti.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:25)
at org.activiti.engine.impl.el.JuelExpression.getValue(JuelExpression.java:48)
... 363 more
So I understand problem is that Process engine does not use right application context, because subscription service is autowired to other classes just fine. But I don't know how to fix it.
Web module is purely annotation based:
#EnableAutoConfiguration
#Configuration
#EntityScan(basePackages = "cz.muni.fi.cep")
#ComponentScan(basePackages = "cz.muni.fi.cep")
public class App extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
...
}
And Activiti configuration:
#Configuration
public class ActivitiConfig {
#Bean
public ProcessEngine processEngine(ProcessEngineConfigurationImpl pec, ApplicationContext applicationContext) throws Exception {
ProcessEngineFactoryBean pe = new ProcessEngineFactoryBean();
pe.setProcessEngineConfiguration(pec);
pe.setApplicationContext(applicationContext);
return pe.getObject();
}
#Bean
public ProcessEngineConfigurationImpl getProcessEngineConfiguration(
DataSource dataSource,
PlatformTransactionManager transactionManager,
ApplicationContext context) {
SpringProcessEngineConfiguration pec = new SpringProcessEngineConfiguration();
pec.setDataSource(dataSource);
pec.setDatabaseSchemaUpdate("true");
pec.setJobExecutorActivate(true);
pec.setHistory("full");
pec.setMailServerPort(2025);
pec.setDatabaseType("mysql");
pec.setTransactionManager(transactionManager);
pec.setApplicationContext(context);
return pec;
}
#Bean
public RuntimeService getRuntimeService(ProcessEngine processEngine) {
return processEngine.getRuntimeService();
}
...
}
Also, maybe order of context creation has somethong to do with this.
Everything looks OK, I believe it might be something as simple as the subscription service not being scanned (does it belong to package cz.muni.fi.cep?), or Spring assigning another name to the subscription service bean (i.e. dbSubscriptionService or dBSubscriptionService instead of just subscriptionService).
Try replacing #Service in DBSubscriptionService class by #Service("subscriptionService") and it should work.
I have the following in my class:
public class Manager {
private Apple apple = AppleFactory.createInstance();
// .....
}
appContext.xml:
<bean id="manager" class="Manager"/>
AppleFactory is an external library on which I do not have any control over. I use xml configuration(appContext.xml) for wiring the beans. How can I inject the field apple from appContext.xml?
<bean id="apple" class="AppleFactory" factory-method="createInstance" />
<bean id="manager" class="Manager"/>
<context:annotation-config />
Your manager
public class Manager {
#Autowired
private Apple apple;
}
Should do the trick.
See the reference guide and Initializing Spring bean from static method from another Class?
You can use following configuration :
<bean id="apple" class="jarpackagename.AppleFactory"
factory-method="createInstance">
</bean>
<bean id="manager" class="pkgname.Manager">
<property name="apple" ref="apple">
</bean>
You can configure Manager bean as follows
<bean class="xxx.Manager">
<property name="apple">
<bean class="yyy.AppleFactory" factory-method="createInstance" />
</property>
</bean>
This question already has answers here:
Howto get rid of <mvc:annotation-driven />?
(4 answers)
Closed 9 years ago.
What exactly would be an equivalent manual configuration to mvc:annotation-driven in spring mvc? Because my webapp implements RequestMappingHandlerMapping, I cannot use mvc:annotation-driven but have to configure this myself.
Specifically I'm wondering what configuration has to be included in order for the #Async annotation to work. I am not sure if it does atm. I'm starting a background task at startup which is supposed to run as long as the webapp is running and it seems to me that the whole server waits for this (never-ending) method to finish. The #Async-Method is in a worker-service which gets called by another service on #PostConstruct.
Here are the two classes:
#Service
public class ModuleDirectoryWatcher{
#Autowired
ModuleDirectoryWatcherWorker worker;
#PostConstruct
public void startWatching() {
worker.startWatching();
}
}
#Service
public class ModuleDirectoryWatcherWorker {
#Async
public void startWatching() {
createPluginDir();
initializeClassloader();
initializeWatcher();
watch();
}
}
The relevant part of my applicationContext.xml looks like this so far:
<bean name="handlerAdapter"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"</bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</list>
</property>
</bean>
<bean name="handlerMapping"
class="com.coderunner.caliope.module.api.impl.ModuleHandlerMapping">
</bean>
Now I feel silly... In order to work, #Async and #Scheduled need
<task:annotation-driven executor="myExecutor" scheduler="myScheduler" />
<task:executor id="myExecutor" pool-size="5" />
<task:scheduler id="myScheduler" pool-size="10" />
even if you don't use
Maybe it helps someone out there
I keep getting this error, and can't figure out why.. yes I know there many people had similar issues, but reading the answers they got, does not solve my problem.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.service.ContactService net.controller.ContactController.contactService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [net.service.ContactService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
here is the controller:
#Controller
#SessionAttributes
public class ContactController {
#Autowired
private ContactService contactService;
//methods...
}
the ContactServiceImpl
#Service("contactService")
#Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class ContactServiceImpl implements ContactService {
#Autowired
private ContactDao contactDao;
public ContactServiceImpl() {
}
#Override
#Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void addContact(Contact contact) {
contactDao.saveContact(contact);
}
#Override
public List<Contact> getContacts() {
return contactDao.getAllContacts();
}
}
the ContactDaoImpl
#Repository("contactDao")
public class ContactDaoImpl implements ContactDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public void saveContact(Contact contact) {
sessionFactory.getCurrentSession().saveOrUpdate(contact);
}
#Override
#SuppressWarnings("unchecked")
public List<Contact> getAllContacts() {
return (List<Contact>) sessionFactory.getCurrentSession().createQuery("from contact c").list();
}
}
and the spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="classpath:jdbc.properties" />
<context:component-scan base-package="net.controller" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>net.form.Contact</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
In spring servlet .xml :
<context:component-scan base-package="net.controller" />
(I assumed that the service impl is in the same package as the service interface "net.service")
I think you have to add the package net.service (or all of net) to the component scan. Currently spring only searches in net.controller for components and as your service impl is in net.service, it will not be instantiated by spring.
I was getting this same error and searching for it led me here. My fix appeared to be simply to add #Component annotation to the implementation of the abstract service.
In this case, that would look like:
import org.springframework.stereotype.Component;
...
#Component
public class ContactServiceImpl implements ContactService {
Well there's a problem with the creation of the ContactServiceImpl bean. First, make sure that the class is actually instantiated by debugging the no-args constructor when the Spring context is initiated and when an instance of ContactController is created.
If the ContactServiceImpl is actually instantiated by the Spring context, but it's simply not matched against your #Autowire annotation, try being more explicit in your annotation injection. Here's a guy dealing with a similar problem as yours and giving some possible solutions:
http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/
If you ask me, I think you'll be ok if you replace
#Autowired
private ContactService contactService;
with:
#Resource
#Qualifier("contactService")
private ContactService contactService;
When you get this error some annotation is missing.
I was missing #service annotation on service. When I added that annotation it worked fine for me.
I've faced the same issue today. Turned out to be I forgot to mention #Service/#Component annotation for my service implementation file, for which spring is not able autowire and failing to create the bean.
I had exactly the same problem
try to put the two classes in the same package and add line in the pom.xml
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-web </artifactId>
<version> 1.2.0.RELEASE </version>
</dependency>
In java config,make sure you have import your config in RootConfig like this
#Import(PersistenceJPAConfig.class)
Encountered similar error, and tried the solutions earlier mentioned in this post but none of them worked for me. What finally resolved the issue was to set #Autowired(required = false)
I'm using Spring to define stages in my application. It's configured that the necessary class (here called Configurator) is injected with the stages.
Now I need the List of Stages in another class, named LoginBean. The Configurator doesn't offer access to his List of Stages.
I cannot change the class Configurator.
My Idea:
Define a new bean called Stages and inject it to Configurator and LoginBean.
My problem with this idea is that I don't know how to transform this property:
<property ...>
<list>
<bean ... >...</bean>
<bean ... >...</bean>
<bean ... >...</bean>
</list>
</property>
into a bean.
Something like this does not work:
<bean id="stages" class="java.util.ArrayList">
Can anybody help me with this?
Import the spring util namespace. Then you can define a list bean as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<util:list id="myList" value-type="java.lang.String">
<value>foo</value>
<value>bar</value>
</util:list>
The value-type is the generics type to be used, and is optional. You can also specify the list implementation class using the attribute list-class.
Here is one method:
<bean id="stage1" class="Stageclass"/>
<bean id="stage2" class="Stageclass"/>
<bean id="stages" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="stage1" />
<ref bean="stage2" />
</list>
</constructor-arg>
</bean>
<bean id="someBean"
class="com.somePackage.SomeClass">
<property name="myList">
<list value-type="com.somePackage.TypeForList">
<ref bean="someBeanInTheList"/>
<ref bean="someOtherBeanInTheList"/>
<ref bean="someThirdBeanInTheList"/>
</list>
</property>
</bean>
And in SomeClass:
class SomeClass {
List<TypeForList> myList;
#Required
public void setMyList(List<TypeForList> myList) {
this.myList = myList;
}
}
Another option is to use JavaConfig. Assuming that all stages are already registered as spring beans you just have to:
#Autowired
private List<Stage> stages;
and spring will automatically inject them into this list. If you need to preserve order (upper solution doesn't do that) you can do it in that way:
#Configuration
public class MyConfiguration {
#Autowired
private Stage1 stage1;
#Autowired
private Stage2 stage2;
#Bean
public List<Stage> stages() {
return Lists.newArrayList(stage1, stage2);
}
}
The other solution to preserve order is use a #Order annotation on beans. Then list will contain beans ordered by ascending annotation value.
#Bean
#Order(1)
public Stage stage1() {
return new Stage1();
}
#Bean
#Order(2)
public Stage stage2() {
return new Stage2();
}
Stacker posed a great answer, I would go one step farther to make it more dynamic and use Spring 3 EL Expression.
<bean id="listBean" class="java.util.ArrayList">
<constructor-arg>
<value>#{springDAOBean.getGenericListFoo()}</value>
</constructor-arg>
</bean>
I was trying to figure out how I could do this with the util:list but couldn't get it work due to conversion errors.
I think you may be looking for org.springframework.beans.factory.config.ListFactoryBean.
You declare a ListFactoryBean instance, providing the list to be instantiated as a property withe a <list> element as its value, and give the bean an id attribute. Then, each time you use the declared id as a ref or similar in some other bean declaration, a new copy of the list is instantiated. You can also specify the List class to be used.
<bean id="student1" class="com.spring.assin2.Student">
<property name="name" value="ram"></property>
<property name="id" value="1"></property>
<property name="listTest">
<list value-type="java.util.List">
<ref bean="test1"/>
<ref bean="test2"/>
</list>
</property>
</bean>
define those beans(test1,test2) afterwards :)
Inject list of strings.
Suppose you have Countries model class that take list of strings like below.
public class Countries {
private List<String> countries;
public List<String> getCountries() {
return countries;
}
public void setCountries(List<String> countries) {
this.countries = countries;
}
}
Following xml definition define a bean and inject list of countries.
<bean id="demoCountryCapitals" name="demoCountryCapitals" class="com.sample.pojo.Countries">
<property name="countries">
<list>
<value>Iceland</value>
<value>India</value>
<value>Sri Lanka</value>
<value>Russia</value>
</list>
</property>
</bean>
Reference link
Inject list of Pojos
Suppose if you have model class like below.
public class Country {
private String name;
private String capital;
.....
.....
}
public class Countries {
private List<Country> favoriteCountries;
public List<Country> getFavoriteCountries() {
return favoriteCountries;
}
public void setFavoriteCountries(List<Country> favoriteCountries) {
this.favoriteCountries = favoriteCountries;
}
}
Bean Definitions.
<bean id="india" class="com.sample.pojo.Country">
<property name="name" value="India" />
<property name="capital" value="New Delhi" />
</bean>
<bean id="russia" class="com.sample.pojo.Country">
<property name="name" value="Russia" />
<property name="capital" value="Moscow" />
</bean>
<bean id="demoCountryCapitals" name="demoCountryCapitals" class="com.sample.pojo.Countries">
<property name="favoriteCountries">
<list>
<ref bean="india" />
<ref bean="russia" />
</list>
</property>
</bean>
Reference Link.
Use the util namespace, you will be able to register the list as a bean in your application context. You can then reuse the list to inject it in other bean definitions.
As an addition to Jakub's answer, if you plan to use JavaConfig, you can also autowire that way:
import com.google.common.collect.Lists;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
<...>
#Configuration
public class MyConfiguration {
#Bean
public List<Stage> stages(final Stage1 stage1, final Stage2 stage2) {
return Lists.newArrayList(stage1, stage2);
}
}
You just remove id out of beans inside <list> tag. Like this:
<property name="listStaff">
<list>
<bean class="com.test.entity.Staff">
<constructor-arg name="name" value = "Jonh"/>
<constructor-arg name="age" value = "30"/>
</bean>
<bean class="com.test.entity.Staff">
<constructor-arg name="name" value = "Jam"/>
<constructor-arg name="age" value = "21"/>
</bean>
</list>
</property>
Use list-class attribute in util:list to make a standalone list of any particular type. for example if you want to make list of type ArrayList:
<util:list id="namesList" list-class="java.util.ArrayList" value-type="java.lang.String">
<value>Abhay</value>
<value>ankit</value>
<value>Akshansh</value>
<value>Db</value>
</util:list>
or if you want to make a list of type LinkedList then :
<util:list id="namesList" list-class="java.util.LinkedList" value-type="java.lang.String">
<value>Abhay</value>
<value>ankit</value>
<value>Akshansh</value>
<value>Db</value>
</util:list>
And this is how to inject set in some property in Spring:
<bean id="process"
class="biz.bsoft.processing">
<property name="stages">
<set value-type="biz.bsoft.AbstractStage">
<ref bean="stageReady"/>
<ref bean="stageSteady"/>
<ref bean="stageGo"/>
</set>
</property>
</bean>