Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Batch@StepScope无法生成CGLIB子类_Java_Spring_Spring Batch_Spring Aop_Cglib - Fatal编程技术网

Java Spring Batch@StepScope无法生成CGLIB子类

Java Spring Batch@StepScope无法生成CGLIB子类,java,spring,spring-batch,spring-aop,cglib,Java,Spring,Spring Batch,Spring Aop,Cglib,编辑 我创建了一个复制该问题的测试项目。可在以下网址找到 首先运行maven命令exec:java,以启动HSQL数据库。然后可以运行JUnit测试MigrationJobConfigurationTest,以加载Spring应用程序上下文 原始问题 @Configuration public class MigrationJobConfiguration { @Autowired private JobBuilderFactory jobs; @Autowired

编辑

我创建了一个复制该问题的测试项目。可在以下网址找到

首先运行maven命令
exec:java
,以启动HSQL数据库。然后可以运行JUnit测试
MigrationJobConfigurationTest
,以加载Spring应用程序上下文

原始问题

@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
    ...
}
启动Spring批处理应用程序时,Spring加载作业配置时出现以下异常:

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
这是由我的作业配置中的
@StepScope
注释引起的。它试图用CGLIB代理一个类,而CGLIB已经用JDK代理了,我不知道这个JDK代理来自哪里

我也尝试过使用
@Scope(value=“step”,proxyMode=ScopedProxyMode.NO)
,但是在调用JDK代理时,我得到了一个堆栈溢出错误,它一直在调用自己

如果我删除
@StepScope
注释,应用程序将正确启动,但我需要能够将它们用于我的工作

弹簧配置

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

//作业存储库等
...
迁移作业配置

@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
    ...
}
@配置
公共类迁移作业配置{
@自动连线
私人建筑工地;
@自动连线
私人StepBuilderFactorySteps;
@自动连线
私有迁移服务迁移服务;
@豆子
公共作业迁移作业(){
返回作业。获取(“迁移作业”)
.start(migrateCrfStep())
.next(indexRequestsStep())
.build();
}
@豆子
公共步骤migrateCrfStep(){
返回步骤。获取(“migrateCrfStep”)
.tasklet(migrateCrfTasklet())
.build();
}
@豆子
公共步骤索引请求步骤(){
返回步骤。获取(“indexRequestsStep”)
.chunk(5)
.reader(indexRequestReader())
.processor(indexRequestProcessor())
.writer(indexRequestWriter())
.build();
}
@豆子
@步进镜
公共迁移ECRTasklet迁移ECRTasklet(){
返回新的MigrateCrfTasklet();
}
@豆子
@步进镜
公共IndexRequestItemReader indexRequestReader(){
返回新的IndexRequestItemReader();
}
@豆子
@步进镜
公共IndexRequestItemProcessor indexRequestProcessor(){
返回新的IndexRequestItemProcessor();
}
@豆子
@步进镜
公共IndexRequestItemWriter indexRequestWriter(){
返回新的IndexRequestItemWriter();
}
//二传手
...
}
轻松从配置文件中删除
;您不需要显式添加它,因为它是在批处理命名空间中定义的(如中所述)

我还不能为您提供实际的答案,但我已经调试了您提供的示例,现在正在发生这种情况:

  • @Configuration
    定义阅读器可以看到
    @StepScope
    注释,该注释用
    @Scope(value=“step”,proxyMode=ScopedProxyMode.TARGET_CLASS)进行注释。
  • reader的CGLIB子类被创建并注册为
    reader
    ,而原始bean被注册为
    scopedTarget.reader
  • StepScope
    启动和后处理
    step
    scoped bean。它检测CGLIB扩展的
    读取器
    定义,并尝试为该=>错误创建代理
冲突中有两种代理机制。有一件事情真的很奇怪,在我看来,这是永远不会起作用的。将尝试通过Spring JIRA进行搜索


更新

找到解决方案-您需要为步骤范围:

<bean class="org.springframework.batch.core.scope.StepScope">
    <property name="autoProxy" value="false" />
</bean>


这将导致相同的异常。这为我解决了该症状。Spring范围规则充其量是间接的,但一旦你掌握了它们,就有意义了。这在我创建的测试项目中是有效的,但由于某些原因,还没有在我的主项目中。我现在用
@EnableBatchProcessing
将XML更改为Java配置,它可以工作。@Pavel在使用@StepScope时,如何将autoProxy设置为false?这是在没有XML配置的情况下发生的。@gsndev如果您没有使用XML配置,您将不会遇到我的回答中描述的冲突(这是OP的问题)。如果您在没有XML配置的情况下遇到类似的异常,那么我建议您提出单独的问题。