0

I am trying to create a bean and am having some issues. Here is my current configuration for it.

    @Bean(name = TDA_JDBC_CURSOR_ITEM_READER)
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public TdaJdbcCursorItemReader<PostDatedAchIn> tdaJdbcCursorItemReader(@Value("#{jobExecutionContext['current.business.date']}") final String currentBusinessDate) {

    SqlStatementHelper sqlStatementHelper = new SqlStatementHelper(PostDatedAchInConstants.POST_DATED_ACH_IN_PROPERTY_FILE,
            PostDatedAchInConstants.POST_DATED_ACH_IN_PROPERTY_ALT_FILE);
    String sqlStatement = sqlStatementHelper.getSqlStatement(PostDatedAchInConstants.RETRIEVE_POST_DATED_ACH_IN);

    TdaJdbcCursorItemReader<PostDatedAchIn> tdaJdbcCursorItemReader = new TdaJdbcCursorItemReader<PostDatedAchIn>();

    tdaJdbcCursorItemReader.setDataSource(prodDataSource);
    tdaJdbcCursorItemReader.setSql(sqlStatement);
    tdaJdbcCursorItemReader.setRowMapper(new PostDatedAchInRowMapper());

    ArrayList<String> parameters = new ArrayList<String>();
    parameters.add(currentBusinessDate);
    parameters.add(currentBusinessDate);
    parameters.add(currentBusinessDate);

    ListPreparedStatementSetter preparedStatementSetter = new ListPreparedStatementSetter();
    preparedStatementSetter.setParameters(parameters);
    tdaJdbcCursorItemReader.setPreparedStatementSetter(preparedStatementSetter);

    return tdaJdbcCursorItemReader;
}

The main problem is without the ScopedProxyMode it uses interfaces and blows up when it tries to use the bean later in the job. But when I add the scoping, then it blows up when trying to access the jobexecutioncontext. So how can I achieve both things with this bean?

Update I changed to @JobScope and do not have an issue with the context, but get this exception when it is trying to instantiate the bean and open the database.

    2018-10-31 09:00:43,994 ERROR [o.s.batch.core.step.AbstractStep:AbstractStep.java:execute:229 - main] - Encountered an error executing step achFulfillment_postDatedAchInJob_step1_scheduleAchIns in job achFulfillmentPostDatedAchInJob
java.lang.ClassCastException: com.sun.proxy.$Proxy110 cannot be cast to org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader$$FastClassBySpringCGLIB$$ebb633d0.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
    at com.tdameritrade.commons.batch.TdaJdbcCursorItemReader$$EnhancerBySpringCGLIB$$9110d31d.open(<generated>)
    at com.tdameritrade.ctg.ach.fulfillment.util.AggregatingJdbcItemReader.open(AggregatingJdbcItemReader.java:161)
    at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:96)
    at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:310)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:197)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
    at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144)
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128)
    at com.tdameritrade.ctg.ach.fulfillment.util.MoneyMovementHelper.getJobExecution(MoneyMovementHelper.java:155)
    at com.tdameritrade.ctg.ach.fulfillment.util.MoneyMovementHelper.getJobExecution(MoneyMovementHelper.java:136)
    at com.tdameritrade.ctg.ach.batch.postdatedachinjob.PostDatedAchInBatchConfigTest.testLaunchJob(PostDatedAchInBatchConfigTest.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Patrick Aquilone
  • 584
  • 2
  • 11
  • 28
  • Why on earth would your item reader be session scoped? It should either be `@StepScope` or `@JobScope` else it simply won't work. – M. Deinum Oct 31 '18 at 13:55
  • @JobScope errors on proxyMode and looking on the internet someone suggested adding the session. – Patrick Aquilone Oct 31 '18 at 13:57
  • I changed it to value="job" Thanks – Patrick Aquilone Oct 31 '18 at 13:59
  • Making it jobscope doesn't error for the context, but gives me this ClassCastException: com.sun.proxy.$Proxy110 cannot be cast to org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader – Patrick Aquilone Oct 31 '18 at 14:01
  • Looks like something is proxying the proxy.. Nonetheless making it session scoped doesn't make sense as that would make your batch job only executable in the context of a current active web session. I can hardly believe that that is what you want, nor will context resolution work as that is for batch scopes only. – M. Deinum Oct 31 '18 at 14:04
  • You are correct, that is not what I want. I am trying to mimic what we can do in XML config but it seems to be not happy here. The TDA...ItemReader implements ItemReader and has some wrapped extras for checking our data from our database. Confused on why it is not working in annotations. – Patrick Aquilone Oct 31 '18 at 14:06
  • Why does it implement `ItemReader` according to the stacktrace something is trying to cast it to `AbstractItemCountingItemStreamItemReader` so you are already extending some other classes. – M. Deinum Oct 31 '18 at 14:07
  • Sorry my bad. It extends JdbcCursorItemReader which extends AbstractCursorItemReader and goes deeper from there in the spring stuff. – Patrick Aquilone Oct 31 '18 at 14:09
  • Thats what I would expect. Please add the full stacktrace. Adding `@JobScope` should generally work without issues (at least we have about 200 batch jobs with either `@JobSciope` and `@StepScope` and using that without issues.). – M. Deinum Oct 31 '18 at 14:10
  • Added the stack trace. – Patrick Aquilone Oct 31 '18 at 14:12
  • Are you by any change casting yourself in your testcase , `PostDatedAchInBatchConfigTest`? – M. Deinum Oct 31 '18 at 14:14
  • No. Test case is simply attempting to run the job and see it complete. ---- JobExecution jobExecution = MoneyMovementHelper.getJobExecution(jobLauncher, job); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); – Patrick Aquilone Oct 31 '18 at 14:15
  • Or the `AggregatingJdbcItemReader`? A cast is done somewhere and I doubt it is in the spring code (that is quite good in programming against the interface). Or is there some other annotation/interface on the class? As you can see there is a CgLib bases proxy and a JdkDynamic proxy being created for whatever reason. – M. Deinum Oct 31 '18 at 14:16
  • There is a cast in the aggregating but it is on the datatype that is expected from reading the database object. I don't see any others. – Patrick Aquilone Oct 31 '18 at 14:18
  • Well something is triggering weird proxy behavior. What happens if you just use `@JobScope`? Do you have some introductions in your code/configuration? At least the `DelegatingIntroductionInterceptor` hints on that. – M. Deinum Oct 31 '18 at 14:21

0 Answers0