Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"IllegalArgumentException: Only 1 out of 2 arguments could be assigned" using MethodInvokingTaskletAdapter + NamedParameterJdbcTemplate #3794

Closed
alessandrococco opened this issue Oct 19, 2020 · 1 comment
Labels
for: backport-to-4.2.x Issues that will be back-ported to the 4.2.x line in: core type: bug
Milestone

Comments

@alessandrococco
Copy link

I'm using Spring Boot 2.3.4 in a kotlin 1.4.10 project.

Bug description

I have the following MethodInvokingTaskletAdapter:

    @Bean
    @StepScope
    fun myTasklet(): Tasklet {
        val tasklet = MethodInvokingTaskletAdapter()

        // jdbcTemplate.update("UPDATE ...",  MapSqlParameterSource("value", value))

        tasklet.setTargetObject(jdbcTemplate) // NamedParameterJdbcTemplate
        tasklet.setTargetMethod("update")
        tasklet.setArguments(
            arrayOf(
                "UPDATE ...",
                MapSqlParameterSource("value", value)
            )
        )
        return tasklet
    }

When the tasklet starts I get this exception:


java.lang.IllegalArgumentException: Only 1 out of 2 arguments could be assigned.
	at org.springframework.batch.item.adapter.HippyMethodInvoker.findMatchingMethod(HippyMethodInvoker.java:84) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:188) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.batch.item.adapter.AbstractMethodInvokingDelegator.doInvoke(AbstractMethodInvokingDelegator.java:112) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.item.adapter.AbstractMethodInvokingDelegator.invokeDelegateMethod(AbstractMethodInvokingDelegator.java:62) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter.execute(MethodInvokingTaskletAdapter.java:53) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_211]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_211]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_211]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_211]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at com.sun.proxy.$Proxy85.execute(Unknown Source) ~[na:na]
	at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:410) [spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136) [spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:319) [spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:147) [spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:140) [spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:155) [spring-batch-test-4.2.4.RELEASE.jar:4.2.4.RELEASE]
	at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:144) [spring-batch-test-4.2.4.RELEASE.jar:4.2.4.RELEASE]

I tried to debug the HippyMethodInvoker: I noticed that the correct match is found but it is overwritten in the if:

image

@hpoettker
Copy link
Contributor

The problem is that the current logic gives the candidate update(String sql, Map<String, ?> paramMap) a perfect of typeDiffWeight of 0 as only the String parameter is actually weighed.

The correct method to choose is update(String sql, SqlParameterSource paramSource) which gets a non-zero weight because MapSqlParameterSource is a subtype of SqlParameterSource.

@fmbenhassine fmbenhassine added in: core and removed status: waiting-for-triage Issues that we did not analyse yet labels Aug 9, 2021
@fmbenhassine fmbenhassine added this to the 4.3.4 milestone Aug 9, 2021
@fmbenhassine fmbenhassine added the for: backport-to-4.2.x Issues that will be back-ported to the 4.2.x line label Aug 9, 2021
fmbenhassine added a commit to fmbenhassine/spring-batch-lab that referenced this issue Sep 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: backport-to-4.2.x Issues that will be back-ported to the 4.2.x line in: core type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants