由以下原因引起:java.lang.ClassNotFoundException:com.thoughtworks.xstream.core.DefaultConverterLookup - Spring 批处理 + 流

Caused by: java.lang.ClassNotFoundException: com.thoughtworks.xstream.core.DefaultConverterLookup - Spring Batch + Stream

我正在开发 Spring Boot + Batch 项目并从 xls 文件中读取数据,同时读取数据时出现以下错误。

我已经添加了 xstream 版本 1.4.11.1Spring OXM 依赖项仍然存在,它给出了错误。启动版本为 2.1.1.RELEASE.

错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerItemReader' defined in class path resource [com/example/config/JobConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.xml.StaxEventItemReader]: Factory method 'customerItemReader' threw exception; nested exception is java.lang.NoClassDefFoundError: com/thoughtworks/xstream/core/DefaultConverterLookup
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=13=](AbstractBeanFactory.java:320) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    at com.example.ReadingXmlApplication.main(ReadingXmlApplication.java:12) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.item.xml.StaxEventItemReader]: Factory method 'customerItemReader' threw exception; nested exception is java.lang.NoClassDefFoundError: com/thoughtworks/xstream/core/DefaultConverterLookup
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    ... 18 common frames omitted
Caused by: java.lang.NoClassDefFoundError: com/thoughtworks/xstream/core/DefaultConverterLookup
    at org.springframework.oxm.xstream.XStreamMarshaller.<init>(XStreamMarshaller.java:140) ~[spring-oxm-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at com.example.config.JobConfiguration.customerItemReader(JobConfiguration.java:33) ~[classes/:na]
    at com.example.config.JobConfiguration$$EnhancerBySpringCGLIB$c5d7e6f.CGLIB$customerItemReader(<generated>) ~[classes/:na]
    at com.example.config.JobConfiguration$$EnhancerBySpringCGLIB$c5d7e6f$$FastClassBySpringCGLIB$2cc440.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at com.example.config.JobConfiguration$$EnhancerBySpringCGLIB$c5d7e6f.customerItemReader(<generated>) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_162]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_162]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_162]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    ... 19 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.thoughtworks.xstream.core.DefaultConverterLookup
    at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_162]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_162]
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) ~[na:1.8.0_162]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_162]
    ... 31 common frames omitted

pom.xml

<dependencies>
    <!-- Spring Starter Batch -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>

    <!-- Spring OXM -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
    </dependency>

    <!-- Spring Starter JDBC -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <!-- H2 -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!-- MYSQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- XSTREAM -->
    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.4.11.1</version>
    </dependency>

    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.2</version>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

JobConfiguration.java

@Configuration
public class JobConfiguration {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public StaxEventItemReader<Customer> customerItemReader(){
        Map<String, Class> aliases = new HashMap<>();
        aliases.put("customer", Customer.class);

        XStreamMarshaller ummarshaller = new XStreamMarshaller();
        ummarshaller.setAliases(aliases);

        StaxEventItemReader<Customer> reader = new StaxEventItemReader<>();
        reader.setResource(new ClassPathResource("/data/customer.xml"));
        reader.setFragmentRootElementName("customer");
        reader.setUnmarshaller(ummarshaller);

        return reader;
    }

    @Bean
    public ItemWriter<Customer> customerItemWriter(){
        return items -> {
            for (Customer customer : items) {
                System.out.println(customer.toString());
            }
        };
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<Customer, Customer>chunk(10)
                .reader(customerItemReader())
                .writer(customerItemWriter())
                .build();
    }

    @Bean
    public Job job() {
        return jobBuilderFactory.get("job")
                .start(step1())
                .build();
    }
}

customer.xml

<?xml version="1.0" encoding="UTF-8" ?>
<customers>
    <customer>
        <id>1</id>
        <firstName>John</firstName>
        <lastName>Doe</lastName>
        <birthdate>10-10-1988 19:43:23</birthdate>
    </customer>
    <customer>
        <id>2</id>
        <firstName>James</firstName>
        <lastName>Moss</lastName>
        <birthdate>01-04-1991 10:20:23</birthdate>
    </customer>
    <customer>
        <id>3</id>
        <firstName>Jonie</firstName>
        <lastName>Gamble</lastName>
        <birthdate>21-07-1982 11:12:13</birthdate>
    </customer>
......

我在做同样的事情时遇到了同样的问题。

我在 mkyong.com 找到了适合我的解决方案。

class DefaultConverterLookup 属于 xstream.jar。并且您需要在 pom.xml 或您正在使用的任何依赖项管理中添加以下依赖项。

<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.11.1</version>
</dependency>