2

I want to inject a string into a bean using constructor injection. Basically I have the following class:

@Component
@StepScope
public class MyClass {

    public MyClass (@Value("#{jobParameters['directory']}") final String directory) {
        // ...
    }

}

When I run my application I get the following stacktrace:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.byteArrayItemReader' defined in file [...]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [my.package.MyClass]: No default constructor found; nested exception is java.lang.NoSuchMethodException: my.package.MyClass.<init>()
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1105) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1050) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:345) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.batch.core.scope.StepScope.get(StepScope.java:113) ~[spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget(CglibAopProxy.java:686) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:636) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at my.package.MyClass$$EnhancerBySpringCGLIB$$cc4837cc.close(<generated>) ~[classes/:na]
    at org.springframework.batch.item.support.CompositeItemStream.close(CompositeItemStream.java:85) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep.close(TaskletStep.java:305) ~[spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:271) ~[spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135) [spring-batch-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at my.package.QueueTaskExecutor$TaskRunner.run(QueueTaskExecutor.java:115) [classes/:na]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [na:1.8.0_66]
    at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_66]
    at java.lang.Thread.run(Unknown Source) [na:1.8.0_66]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [my.package.MyClass]: No default constructor found; nested exception is java.lang.NoSuchMethodException: my.package.MyClass.<init>()
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1098) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    ... 28 common frames omitted
Caused by: java.lang.NoSuchMethodException: my.package.MyClass.<init>()
    at java.lang.Class.getConstructor0(Unknown Source) ~[na:1.8.0_66]
    at java.lang.Class.getDeclaredConstructor(Unknown Source) ~[na:1.8.0_66]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
    ... 29 common frames omitted

So how do I correctly inject a string value using the constructor?

stevecross
  • 5,588
  • 7
  • 47
  • 85

1 Answers1

7

If you need to inject values into the bean via constructor parameters, you have to annotate the constructor with @Autowired, otherwise the default constructor will be used. So, it has to be as:

@Autowired
public MyClass (@Value("#{jobParameters['directory']}") final String directory) {
    // ...
}
Stanislav
  • 27,441
  • 9
  • 87
  • 82