0
votes

I am consuming a JMS ObjectMessage through a listener written in Spring Boot. I am sending the ObjectMessage through my Camel application to ActiveMQ queue and I am listening to the queue from my listener class in my Spring Boot application.

Code:

final BindyCsvDataFormat bindy = new BindyCsvDataFormat(EquityFeeds.class);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
CamelContext _ctx = new DefaultCamelContext(); 
_ctx.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
_ctx.addRoutes(new RouteBuilder() {

    public void configure() throws Exception {
        from("file:src/main/resources?fileName=data.csv")               
            .unmarshal(bindy)
            .split(body())
            .streaming().to("jms:queue:javaobjects.upstream.queue");
    }
});

Here is my POJO class EquityFeeds:

@CsvRecord(separator = ",",skipFirstLine = true)
public class EquityFeeds implements Serializable {

    private static final long serialVersionUID = 1L;

    @DataField(pos = 1) 
    private String externalTransactionId;

    @DataField(pos = 2)
    private String clientId;

    // other fields and getters setters
    ...

In ActiveMQ queue I am receiving the message as:

camelproject.EquityFeeds@1665425

My JMS listener in Spring Boot:

@JmsListener(destination = "javaobjects.upstream.queue")
public void capitalIQProcessor(final Message objectMessage) throws JMSException {
    Object messageData = null;

    if(objectMessage instanceof ObjectMessage) {
        ObjectMessage objMessage = (ObjectMessage) objectMessage;
        System.out.println("Starting Object Message.");

        Object object = objMessage.getObject();

        EquityFeeds equityFeeds = (EquityFeeds) object;

        System.out.println("Object: "+equityFeeds.toString());
    }    
}

I am getting an Exception @ line Object object = objMessage.getObject();:

capitalIQProcessor(javax.jms.Message) throws javax.jms.JMSException' threw exception; nested exception is javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: camelproject.EquityFeeds. Caused by: javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: camelproject.EquityFeeds. Caused by: java.lang.ClassNotFoundException: camelproject.EquityFeeds

Through Stack Overflow and other posts on the net I made the following changes:

  1. I made the changes to wrapper.conf (apache-activemq-5.15.11-bin\apache-activemq-5.15.11\bin\win64)

    1. Added then entry: wrapper.java.classpath.3=C:\Users\sidbharg\eclipse-workspace\Sid\target\camelproject-0.0.1-SNAPSHOT.jar This is the location of the .jar file where I have my POJO (EquityFeeds).
    2. Also added the entry: wrapper.java.additional.13=-Dorg.apache.activemq.SERIALIZABLE_PACKAGES="*"
  2. In My Consumer code I also added activeMQConnectionFactory.setTrustAllPackages(true);:

public ActiveMQConnectionFactory activeMQConnectionFactory() {
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
        activeMQConnectionFactory.setBrokerURL(brokerURL);
        activeMQConnectionFactory.setTrustAllPackages(true);
        return activeMQConnectionFactory;
}

Now what is the issue? Why its giving me the exception. Where I am going wrong? Is there anything which I have forgotten and is needed to be added?

1
Why are you using a JMS ObjectMessage? It's discouraged for multiple reasons.Justin Bertram
@Justin: I understand that its discouraged for mulitple reasons but still I have a requirement to do it and so can't help it.sidd
You have a specific requirement to use ObjectMessage even though technically the data could be transferred in other kinds of messages which are safer and don't suffer from the same limitations? Typically requirements aren't expressed at the implementation level like that.Justin Bertram

1 Answers

0
votes

You need camelproject.EquityFeeds on the classpath of the application consuming the JMS ObjectMessage. Apparently the JVM can't find it and therefore throws a java.lang.ClassNotFoundException.

Also, you don't need those changes to the broker's wrapper.conf. The listener is trying to deserialize the message, not the broker.