Monday, March 30, 2009

JBoss Serialization simple example

I know this is a rather trivial thing, but serializing non-serializable objects is not very well documented online (as far as I could see), so thought I would post an example using the well known solution JBoss Serialization.

What I am doing is trying to add jBPM context variables that are serialized for transport (SOAP), so here a non-serializable web service result object will be serialized.

// Using Jboss to serialize a non-serialziable web service result object.
//
Map<String, Object> contextData = new HashMap<String, Object>();
JBossObjectOutputStream objOut = null;
byte[] serializedResult = null;

try {
    ByteArrayOutputStream out = new ByteArrayOutputStream() ;

    objOut = new JBossObjectOutputStream(out);
    objOut.writeObject(result);
    objOut.close();
    out.close();

    // jboss serialized object into byte array.
    serializedResult = out.toByteArray();
} catch (IOException ioEx) { 
    LOG.error("Unable to serialize the service results object: " 
        + ioEx.getMessage());
} 

// insert into context.
context.put(RESULT_DATA, serializedResult);

// using previously created process instance we can now add this to 
// our jbpm context via a given token.
token.processInstance.getContextInstance().addVariables(context, token);

To un-serialize you just reverse the order above using a ByteArrayInputStream and JBossObjectInputStream.

================ UPDATE =====================

I have cleaned up the above action and provide a reusable utility method to serialize and un-serialize an object to/from a byte array.

/**
 * Converts an object to a serialized byte array.
 * 
 * @param obj Object to be converted.
 * @return byte[] Serialized array representing the object.
 */
public static byte[] getByteArrayFromObject(Object obj) {
    byte[] result = null;
       
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new JBossObjectOutputStream(baos);
        oos.writeObject(obj);
        oos.flush();
        oos.close();
        baos.close();
        result = baos.toByteArray();
    } catch (IOException ioEx) {
        Logger.getLogger("UtilityMethods").error("Error converting object to byteArray", ioEx);
    }
        
    return result;
}

/**
 * Utility method to un-serialize objects from byte arrays.
 * 
 * @param bytes The input byte array.
 * @return The output object.
 */
public static Object getObjectFromByteArray(byte[] bytes) {
    Object result = null;
 
    try {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
 ObjectInputStream ois = new JBossObjectInputStream(bais);
 result = ois.readObject();
 ois.close();
    } catch (IOException ioEx) {
        Logger.getLogger("UtilityMethods").error("Unable to deserialize object from byte array.", 
            ioEx);
    } catch (ClassNotFoundException cnfEx) {
        Logger.getLogger("UtilityMethods").error("No corresponding class for byte array.", 
            cnfEx);
    }
  
    return result;
}