Spring Batch @StepScope nie może generować podklasy CGLIB

EDYTOWAĆ

Stworzyłem projekt testowy, który powiela problem. Można go znaleźć pod adresemhttps://github.com/tomverelst/test-batch.

Najpierw uruchom komendę mavenexec:java uruchomić bazę danych HSQL. Następnie możesz uruchomić test JUnitMigrationJobConfigurationTest aby załadować kontekst aplikacji Spring.

Oryginalne pytanie

Podczas uruchamiania mojej aplikacji Spring Batch pojawia się następujący wyjątek, gdy Spring ładuje konfigurację mojej pracy:

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

Jest to spowodowane przez@StepScope adnotacja w konfiguracji mojej pracy. Próbuje proxy klasy z CGLIB, który jest już proxy z proxy JDK i nie wiem, skąd pochodzi ten serwer proxy JDK.

Próbowałem również użyć@Scope(value = "step", proxyMode = ScopedProxyMode.NO), ale wtedy pojawia się błąd przepełnienia stosu podczas wywoływania serwera proxy JDK, który sam się wywołuje.

Aplikacja zostanie uruchomiona poprawnie, jeśli usunę@StepScope adnotacje, ale muszę być w stanie używać ich do pracy.

Spring config

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

questionAnswers(2)

yourAnswerToTheQuestion