Debesh Nayak
Debesh Nayak

Reputation: 244

Getting com.thoughtworks.xstream.mapper.CannotResolveClassException while converting JSON to CSV using Apache Camel 2.25.0

I am converting JSON to CSV using Spring Boot 2.6.2, Apache Camel 2.25.0, JDK 1.8.

Below is the Camel Route code snippet that I am using for this:

@Override
public void configure() throws Exception {
    // Receive from JSON file 
    from("file:files/input")
            .log("Received file - ${body}")
            // transform JSON to CSV format
            .unmarshal().json()

            .marshal().csv()
    
            // Write to output file
            .log("Writing file - ${body}")
            .to("file:files/output");
}

Source Code: https://github.com/DebeshNayak/camel-json-to-csv

This application builds successfully, but during runtime, I am getting the below error:

2022-01-04 11:10:47.813  INFO 14788 --- [e://files/input] route1                                   : Received file - {
  "fname": "debesh",
  "lname": "nayak"
}
2022-01-04 11:10:47.862 ERROR 14788 --- [e://files/input] o.a.camel.processor.DefaultErrorHandler  : Failed delivery for (MessageId: ID-Debesh-Lenovo-i5-1641274844914-0-2 on ExchangeId: ID-Debesh-Lenovo-i5-1641274844914-0-1). Exhausted after delivery attempt: 1 caught: com.thoughtworks.xstream.mapper.CannotResolveClassException: fname

Message History
---------------------------------------------------------------------------------------------------------------------------------------
RouteId              ProcessorId          Processor                                                                        Elapsed (ms)
[route1            ] [route1            ] [file://files/input                                                            ] [        60]
[route1            ] [log1              ] [log                                                                           ] [        20]
[route1            ] [unmarshal1        ] [unmarshal[org.apache.camel.model.dataformat.JsonDataFormat@5bb0a7b2]          ] [        28]

Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------

com.thoughtworks.xstream.mapper.CannotResolveClassException: fname
    at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:81) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:133) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1487) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1455) ~[xstream-1.4.11.1.jar:1.4.11.1]
    at org.apache.camel.dataformat.xstream.AbstractXStreamWrapper.unmarshal(AbstractXStreamWrapper.java:374) ~[camel-xstream-2.25.0.jar:2.25.0]
    at org.apache.camel.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:69) ~[camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548) ~[camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:138) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:101) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:454) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:223) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:187) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) [camel-core-2.25.0.jar:2.25.0]
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) [camel-core-2.25.0.jar:2.25.0]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_312]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_312]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_312]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_312]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_312]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_312]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_312]

In my project I am using below Maven dependency in the pom.xml:

<properties>
    <java.version>1.8</java.version>
    <camel.version>2.25.0</camel.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-spring-boot-starter</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-stream-starter</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-jackson</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-xstream</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-csv</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

But while using Apache Camel 3.4.2, it is working properly.

Upvotes: 0

Views: 769

Answers (1)

Tom Donohue
Tom Donohue

Reputation: 362

Camel supports a couple of different JSON libraries, and it just so happens that Camel 3 changed its default JSON library from XStream to Jackson, which might be why the code isn't working here. (See CAMEL-5836 for info about the change). The default library is used whenever you use the .json() keyword on its own.

So if you want to use this code with Camel 2.x, or to customise the JSON marshalling/unmarshalling in any way, you can instantiate Jackson explicitly first, and then refer to it in the route, e.g.:

JacksonDataFormat json = new JacksonDataFormat();
// You can also set any Jackson options here

from("file:files/input")
    .log("Received file - ${body}")
    // transform JSON to CSV format, referring to the "json" object above
    .unmarshal(json)

    .marshal().csv()
    
    // Write to output file
    .log("Writing file - ${body}")
    .to("file:files/output");
}

Working with Jackson is a lot simpler than XStream, because it can unmarshal to a simple Java object like a Map, without much configuration.

Upvotes: 1

Related Questions