Reputation: 3023
I want to inject a bean from one context to my controller bean in MVC context. Here is my bean definition from MVC context:
<import resource="another.context.xml"/>
<bean name="myController" class="com.test.spring.web.Controller">
<property name="batchJobRepository" ref="batchJobRepository"/>
</bean>
In the another context I defined a Spring Batch Job repository:
<bean id="batchJobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
</bean>
My controller:
@Controller
public class MyController {
private MapJobRepositoryFactoryBean batchJobRepository;
@RequestMapping("/batch/test")
@ResponseBody
public String batch() {
Set<JobExecution> jes = batchJobRepository
.getJobExecutionDao()
.findRunningJobExecutions("firstJob");
for (JobExecution je : jes) {
System.out.println(je.isRunning());
}
return "Done!";
}
The problem is a tricky one. I got an error:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'myController' defined in class path resource [META-INF/spring/controllers.xml]:
Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException:
Failed to convert property value of type 'com.sun.proxy.$Proxy25 implementing org.springframework.batch.core.repository.JobRepository,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean' for property 'batchJobRepository';
nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy25 implementing org.springframework.batch.core.repository.JobRepository,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean] for property 'batchJobRepository': no matching editors or conversion strategy found
How can I fix it?
UPD
Added controller details.
UPD2
I tried to use
<aop:scoped-proxy proxy-target-class="true"/>
in batchJobRepository
bean. But result is the same: Failed to convert property value of type 'com.sun.proxy.$Proxy17 implementing org.springframework.batch.core.repository.JobRepository
Upvotes: 2
Views: 1672
Reputation: 6540
This problem is caused because you are using the MapJobRepositoryFactoryBean
incorrectly. This bean is actually a factory bean, that will return instances of JobRepository
.
Your stacktrace is essentially saying that it can't cast a bean of type JobRepository
to MapJobRepositoryFactoryBean
and set the property in the controller. It should also be noted that MapJobRepositoryFactoryBean
is a purely in-memory implementation, and will not connect to your database to manage job state.
Change your controller code to the following:
@Controller
public class MyController {
private JobRepository batchJobRepository;
@RequestMapping("/batch/test")
@ResponseBody
public String batch() {
Set<JobExecution> jes = batchJobRepository
.getJobExecutionDao()
.findRunningJobExecutions("firstJob");
for (JobExecution je : jes) {
System.out.println(je.isRunning());
}
return "Done!";
}
}
A more elegant solution would be to declare a JobExplorer
bean as follows:
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="myController" class="com.test.spring.web.Controller">
<property name="jobExplorer" ref="jobExplorer"/>
</bean>
and then use the JobExplorer
bean in your controller like so:
@Controller
public class MyController {
private JobExplorer jobExplorer;
@RequestMapping("/batch/test")
@ResponseBody
public String batch() {
Set<JobExecution> jes = jobExplorer
.findRunningJobExecutions("firstJob");
for (JobExecution je : jes) {
System.out.println(je.isRunning());
}
return "Done!";
}
}
I don't know why you thought that setting your aop config to use Aspect-J would help, but it won't and you shouldn't be using load time weaving if you don't need it.
Upvotes: 3
Reputation: 2203
You should use the anotation @Autowired
on your DI.
@Autowired
private MapJobRepositoryFactoryBean batchJobRepository;
also add the folowing line on your spring context:
<!--AUTOWIRED-->
<context:component-scan base-package="com.system.rest.app.controller" />
Upvotes: -1