Spring Batch @StepScope kann keine CGLIB-Unterklasse generieren

BEARBEITEN

Ich habe ein Testprojekt erstellt, das das Problem repliziert. Es kann bei gefunden werdenhttps://github.com/tomverelst/test-batch.

Führen Sie zuerst den Befehl maven ausexec:java um eine HSQL-Datenbank zu starten. Dann können Sie den JUnit-Test ausführenMigrationJobConfigurationTest zum Laden des Spring-Anwendungskontexts.

Ursprüngliche Frage

Beim Starten meiner Spring Batch-Anwendung tritt die folgende Ausnahme auf, wenn Spring die Konfiguration meines Jobs lädt:

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

Dies wird verursacht durch die@StepScope Anmerkung in der Konfiguration meines Jobs. Es wird versucht, eine Klasse mit CGLIB zu vertreten, die bereits von einem JDK-Proxy vertreten wird, und ich weiß nicht, woher dieser JDK-Proxy stammt.

Ich habe es auch mit versucht@Scope(value = "step", proxyMode = ScopedProxyMode.NO)Beim Aufrufen des JDK-Proxys wird jedoch ein Stapelüberlauffehler angezeigt, der sich selbst weiterhin aufruft.

Die Anwendung startet korrekt, wenn ich die entferne@StepScope Anmerkungen, aber ich muss in der Lage sein, sie für meine Jobs zu verwenden.

Federkonfiguration

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

Antworten auf die Frage(2)

Ihre Antwort auf die Frage