0
votes

I have enqueued a Java object (which holds a record from Oracle table) into ActiveMQ queue as an ObjectMessage. Next I want to retrieve that ObjectMessage and get the Clob Data inside it. If I try this I get error:

java.lang.IllegalStateException: Clobs may not be accessed after serialization

I receive this for the Clob field only. The Integer or String fields are read successfully from the object returned from the queue.

Producer:

public void enqueuToTableQueue(String TableName, Serializable recordObject)
{
    jms_queue_name = TableName.trim().toUpperCase() + "_QUEUE";
    try {
        destination = new ActiveMQQueue(jms_queue_name); 
        producer = producerSession.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);            
        ObjectMessage aRecordObjMsg = producerSession.createObjectMessage(recordObject);
        aRecordObjMsg.setJMSType("OBJECT");
        
        producer.send(aRecordObjMsg);
    } catch (JMSException jex) {
        logger.info(jex);
    } catch (Exception  ex) {
        logger.info(ex);
    }
}

Consumer:

public Object dequeuFromTableQueue(String  tableName){

    try {
         Message msg;
         try {
             msg = consumer.receive();
             if (msg instanceof ObjectMessage) {
                    ObjectMessage objmsg = (ObjectMessage) msg;
                    Object object = objmsg.getObject(); 
                    return object;
                } else {
                    System.out.println("Unrecognized Message type " + msg.getClass());
                }
         } catch (JMSException e) {

             System.out.println("consumer.receive() has thrown JMSException..");
             e.printStackTrace();
         }      
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Exception from Main:

Object obj = queueManager.dequeuFromTableQueue("BillData");
                
if ( obj != null) {
    BillData billData = (BillData) obj;
    System.out.println("Account Num is : " + billData.getACCOUNT_NUM()); // PRINTS SUCCESSFULLY
    
    Reader reader =null;
    try {
        reader = billData.getDATA().getCharacterStream(); //THIS LINE THROWS Exception :java.lang.IllegalStateException: Clobs may not be accessed after serialization 

I am using Hibernate for retrieving the data from Oracle database from producer, and I need to use Hibernate again after reading data from ActiveMQ to save in Postgres.

1

1 Answers

1
votes

In general ObjectMessage usage is discouraged as it introduces coupling of class paths between producers and consumers. Also in recent years security issues have arisen when decoding objects with vulnerable libraries allowing code injection etc. You have to make configuration changes on the client end to allow your objects to be deserialized. These options are documented in the ActiveMQ website docs

Basically your connection factory needs to be configured to allow the various packages that will be touched when deserializing you objects:

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
factory.setTrustedPackages(new ArrayList(Arrays.asList("org.apache.activemq.test,org.apache.camel.test".split(","))));