Spring Batch @StepScope no puede generar una subclase CGLIB
EDITAR
Creé un proyecto de prueba que replica el problema. Se puede encontrar enhttps://github.com/tomverelst/test-batch.
Primero ejecuta el comando mavenexec:java
para iniciar una base de datos HSQL. A continuación, puede ejecutar la prueba JUnitMigrationJobConfigurationTest
para cargar el contexto de la aplicación Spring.
Pregunta original
Al iniciar mi aplicación Spring Batch, obtengo la siguiente excepción cuando Spring está cargando la configuración de mi trabajo:
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy34]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy34
Esto es causado por la@StepScope
anotación en la configuración de mi trabajo. Intenta crear una clase de proxy con CGLIB que ya tiene un proxy con un proxy JDK y no sé de dónde viene este proxy JDK.
También he intentado usar@Scope(value = "step", proxyMode = ScopedProxyMode.NO)
, pero luego aparece un error de desbordamiento de pila al invocar el proxy JDK, que sigue invocándose a sí mismo.
La aplicación se inicia correctamente si quito el@StepScope
anotaciones, pero necesito poder usarlas para mis trabajos.
Configuración de primavera
<context:component-scan base-package="com.jnj.rn2.batch" />
<context:annotation-config />
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean class="org.springframework.batch.core.scope.StepScope" />
// Job repository etc
...
MigrationJobConfiguration
@Configuration
public class MigrationJobConfiguration {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Autowired
private MigrationService migrationService;
@Bean
public Job migrationJob() {
return jobs.get( "migrationJob" )
.start( migrateCrfStep() )
.next( indexRequestsStep() )
.build();
}
@Bean
public Step migrateCrfStep() {
return steps.get( "migrateCrfStep" )
.tasklet( migrateCrfTasklet() )
.build();
}
@Bean
public Step indexRequestsStep() {
return steps.get( "indexRequestsStep" )
.<LegacyRequest,LegacyRequest> chunk( 5 )
.reader( indexRequestReader() )
.processor( indexRequestProcessor() )
.writer( indexRequestWriter() )
.build();
}
@Bean
@StepScope
public MigrateCrfTasklet migrateCrfTasklet() {
return new MigrateCrfTasklet();
}
@Bean
@StepScope
public IndexRequestItemReader indexRequestReader() {
return new IndexRequestItemReader();
}
@Bean
@StepScope
public IndexRequestItemProcessor indexRequestProcessor() {
return new IndexRequestItemProcessor();
}
@Bean
@StepScope
public IndexRequestItemWriter indexRequestWriter() {
return new IndexRequestItemWriter();
}
// Setters
...
}