How do I Serialize a JMS Message?

3.8k views Asked by At

I am attempting to Serialize a JMS Message so that I can turn it into a BLOB and save it into a SQL database.

My first naive attempt used a Serializable class that took it as a field as follows:

private static class SerializableWrapper implements Serializable{
    Message message;
    private SerializableWrapper(Message message){
        this.message = message;
    }

    private Message getMessage() {
        return message;
    }

    private void setMessage(Message message) {
        this.message = message;
    }
    private void writeObject(java.io.ObjectOutputStream out)
            throws IOException{
        out.writeObject(getMessage());
    }

    private void readObject(java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException {
        setMessage((Message) in.readObject());
    }
}

This doesn't work and continues to throw a NotSerializableException for JMSTextMessage. I am unsure whether there are other 3rd party libraries that might help to serialize this, but the requirement for my task is to not have 3rd party dependencies at all.

Is there any good/plausible way to do this without requiring other dependencies?

Edit: I am currently achieving this by unpacking every single property and then reconstructing the message as a whole when deserializing. This method is in my opinion still less than optimal - there are some fields that are non-serializable and I also have to separately deal with the various different subclasses of Message e.g. TextMessage,ByteMessage etc.

private void writeObject(java.io.ObjectOutputStream out)
            throws IOException{
        HashMap<String, Object> properties = new HashMap <String, Object> ();
        HashMap<Integer, Object> metaData = new HashMap<Integer, Object>();
        try {
            Enumeration srcProperties = message.getPropertyNames();
            while (srcProperties.hasMoreElements()) {
                String propertyName = (String) srcProperties.nextElement ();
                properties.put(propertyName, message.getObjectProperty (propertyName));
            }
            //FIXME text/other body not preserved yet, have to preserve the message type eg Text/Byte etc continue after confirming with aditya
            metaData.put(KEY_JMS_CORRELATION_ID, message.getJMSCorrelationID());
            metaData.put(KEY_JMS_DELIVERY_MODE, message.getJMSDeliveryMode());
            metaData.put(KEY_JMS_EXPIRATION, message.getJMSExpiration());
            metaData.put(KEY_JMS_TIMESTAMP, message.getJMSTimestamp());
            metaData.put(KEY_JMS_MESSAGE_ID, message.getJMSMessageID());
            metaData.put(KEY_JMS_PRIORITY, message.getJMSPriority());
            metaData.put(KEY_JMS_REPLY_TO, message.getJMSReplyTo());
            metaData.put(KEY_JMS_TYPE, message.getJMSType());
        } catch (JMSException e) {
            e.printStackTrace();
        }
        out.writeObject(properties);
        out.writeObject(metaData);
    }

    private void readObject(java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException {
        HashMap<String, Object> properties = (HashMap<String, Object>) in.readObject();
        HashMap<Integer, Object> metaData= (HashMap<Integer, Object>) in.readObject();
        System.out.println("JMSMessageUtility - Retrieving Properties: "+properties);
        System.out.println("JMSMessageUtility - Retrieving Metadata: "+metaData);

        Message message = null;
        try {
            ConnectionFactory connectionFactory = new AMQConnectionFactory(CONNECTION_BROKER);
            Destination destination = new AMQAnyDestination(QUEUE_ADDRESS);
            Connection connection = connectionFactory.createConnection();
            Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            message = session.createMessage();
            for(Map.Entry<String, Object> property: properties.entrySet()){
                message.setObjectProperty(property.getKey(), property.getValue());
            }
            message.setJMSCorrelationID(metaData.get(KEY_JMS_CORRELATION_ID) == null? null:(String) metaData.get(KEY_JMS_CORRELATION_ID));
            message.setJMSDeliveryMode((Integer) metaData.get(KEY_JMS_DELIVERY_MODE));
            message.setJMSDestination(destination);
            message.setJMSExpiration((Long) metaData.get(KEY_JMS_EXPIRATION));
            message.setJMSTimestamp((Long) metaData.get(KEY_JMS_TIMESTAMP));
            message.setJMSMessageID((String) metaData.get(KEY_JMS_MESSAGE_ID));
            message.setJMSPriority((Integer) metaData.get(KEY_JMS_PRIORITY));
            message.setJMSReplyTo(null); // no idea what to do with this
            message.setJMSType(metaData.get(KEY_JMS_TYPE) == null? null:(String) metaData.get(KEY_JMS_TYPE));
        } catch (URLSyntaxException e) {
            e.printStackTrace();
        } catch (JMSException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        setMessage(message);
    }
0

There are 0 answers