初始化bean时出现java.lang.NoSuchMethodError

时间:2017-10-20 15:42:38

标签: java spring spring-batch

我正在开发一个基于Spring Batch的应用程序,在我引入ShutdownHook以优雅地停止我的工作后(由https://numberformat.wordpress.com/2012/04/24/shutting-down-spring-batch-jobs-gracefully/的指令引导),每次钩子时我开始得到一些奇怪的异常得到执行(即每次程序终止)

`Exception in thread "Thread-2" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration': Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration.setBeanFactory(Lorg/springframework/beans/factory/BeanFactory;)V
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:370)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:296)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:337)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:252)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at org.springframework.batch.core.launch.support.SimpleJobOperator$$EnhancerBySpringCGLIB$$b81f4553.stop(<generated>)
at com.tsi.tesb.autodeploy.proto.batch.ProcessShutdownListener$1.run(ProcessShutdownListener.java:30)
Caused by: java.lang.NoSuchMethodError: org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration.setBeanFactory(Lorg/springframework/beans/factory/BeanFactory;)V
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$$EnhancerBySpringCGLIB$$dbf00617.setBeanFactory(<generated>)
at org.springframework.context.annotation.ConfigurationClassPostProcessor$EnhancedConfigurationBeanPostProcessor.postProcessPropertyValues(ConfigurationClassPostProcessor.java:442)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
... 22 more`

在搜索类似内容之后,我尝试在POM中设置相同和新版本的Spring组件,但它没有帮助。通过Spring代码进行调试我发现SimpleBatchConfiguration bean在执行shutdown hook时再次被实例化,并且 cglib $ callback 0 设置为null,这可能是问题 - 但不幸的是我无法理解为什么会这样,我在哪个方向上迷失了进一步挖掘。

这可能是一些Spring bug还是我在这里做错了什么?

我的POM:

`<!-- cut for clarity -->

<!-- 
============================================================================
 Dependencies
============================================================================ 
-->
<dependencies>

    <!-- IBM MQ -->
    <dependency>
        <groupId>com.ibm</groupId>
        <artifactId>com.ibm.mq.allclient</artifactId>
        <version>8.0</version>
    </dependency>

    <!-- IBM PCF (local) -->
    <dependency>
        <groupId>com.ibm.mq</groupId>
        <artifactId>com.ibm.mq.pcf</artifactId>
        <version>9.0.0.1</version>
    </dependency>


    <!-- IBM IIB (local) -->
    <dependency>
        <!-- <groupId>com.ibm</groupId>
        <artifactId>com.ibm.iib.integration-api</artifactId>
        <version>10.0.0.3</version> -->
        <groupId>com.ibm.broker</groupId>
        <artifactId>IntegrationAPI</artifactId>
        <version>1.0</version>
    </dependency>

    <!-- db2 api -->
    <dependency>
        <groupId>com.ibm.db2</groupId>
        <artifactId>db2jcc4</artifactId>
        <version>4.19.26</version>
    </dependency>

    <!-- sqlite api -->
    <dependency>
      <groupId>org.xerial</groupId>
      <artifactId>sqlite-jdbc</artifactId>
      <version>3.7.2</version>
    </dependency>

    <!-- Jetty + websocket (for IBM Integration API) -->
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-client</artifactId>
        <version>9.0.5.v20130815</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-http</artifactId>
        <version>9.0.5.v20130815</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-io</artifactId>
        <version>9.0.5.v20130815</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-util</artifactId>
        <version>9.0.5.v20130815</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty.websocket</groupId>
        <artifactId>websocket-api</artifactId>
        <version>9.0.5.v20130815</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty.websocket</groupId>
        <artifactId>websocket-client</artifactId>
        <version>9.0.5.v20130815</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty.websocket</groupId>
        <artifactId>websocket-common</artifactId>
        <version>9.0.5.v20130815</version>
    </dependency>

    <!-- Apache commons compress -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-compress</artifactId>
        <version>1.12</version>
    </dependency>

    <!-- needed to omit BOM in input files -->
    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>

    <!-- SSH -->
    <dependency>
        <groupId>com.jcraft</groupId>
        <artifactId>jsch</artifactId>
        <version>0.1.54</version>
    </dependency>

    <!-- Samba -->
    <dependency>
        <groupId>jcifs</groupId>
        <artifactId>jcifs</artifactId>
        <version>1.3.17</version>
    </dependency>

    <!-- Spring batch -->
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-core</artifactId>
        <version>3.0.8.RELEASE</version> <!-- was 3.0.7 -->
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.0.9.RELEASE</version> <!-- was 4.0.5 -->
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- AoP -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.7.0</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.0</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib-nodep</artifactId>
        <version>3.2.4</version> <!-- was 2.2 -->
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.0.9.RELEASE</version>
    </dependency>


    <!-- Spring OXM -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-oxm -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
        <version>4.0.9.RELEASE</version>
    </dependency>

    <!-- Spring JDBC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.0.9.RELEASE</version>
    </dependency>

    <!-- SLF4J / logpack -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.7.21</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.7</version>
    </dependency>

    <!-- SVN -->
    <dependency>
        <groupId>org.tmatesoft.svnkit</groupId>
        <artifactId>svnkit</artifactId>
        <version>1.8.14</version>
    </dependency>

    <!-- Test dependencies -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>pl.pragmatists</groupId>
        <artifactId>JUnitParams</artifactId>
        <version>1.1.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.3.2.RELEASE</version>
        <scope>test</scope>
    </dependency>
</dependencies>


<!-- cut for clarity  -->`

关闭钩子实现类:

package com.tsi.tesb.autodeploy.proto.batch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.launch.JobExecutionNotRunningException;
import org.springframework.batch.core.launch.JobOperator;
import org.springframework.batch.core.launch.NoSuchJobExecutionException;
import org.springframework.stereotype.Component;

@Component("processShutdownListener")
public class ProcessShutdownListener implements JobExecutionListener{

    private static final Logger LOGGER = LoggerFactory.getLogger(ProcessShutdownListener.class);

    private JobOperator jobOperator;

    @Override
    public void beforeJob(final JobExecution jobExecution) {

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    jobOperator.stop(jobExecution.getId());
                    while(jobExecution.isRunning()) {
                        LOGGER.info("waiting for job to stop...");
                        try {Thread.sleep(100);} catch (InterruptedException e) {}
                    }
                } catch (NoSuchJobExecutionException e) { // ignore
                } catch (JobExecutionNotRunningException e) { // ignore
                }
            }
        });
    }

    @Override
    public void afterJob(JobExecution jobExecution) {
        //do nothing
    }

    public void setJobOperator(JobOperator jobOperator) {
        this.jobOperator = jobOperator;
    }

}

0 个答案:

没有答案