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
    ...
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta