RE: Enums and other serialization woes

From: Jason Stiefel <jasons@xxx.net>
Date: Tue Oct 25 2005 - 07:39:39 PDT

I wrote my own se/deserializer combo for enums. I'll just paste them and
hope it helps you out. The gist of it is you need to know 2 things to
deserialize an enum (and thus those two things need to be serialized) First
is the classname of the enum. Second is the toString value of the enum.
Using those two pieces you can call:

java.lang.Enum.valueOf(Class,String)

----------------------------------

package com.aebn.media.util.hessian;

import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.AbstractSerializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;

/**
 * Serializes Java 1.5 Enumerations
 *
 * @author kp
 */
public class JavaEnumSerializer extends AbstractSerializer {

    private static Log LOG = LogFactory.getLog(JavaEnumSerializer.class);

    public void writeObject(Object obj, AbstractHessianOutput out) throws
IOException {

        Class cl = obj.getClass();

        if (LOG.isDebugEnabled())
            LOG.debug("Writing enum of type " + cl.getName() + " with value:
" + obj.toString());

        out.writeMapBegin(cl.getName());
        out.writeString(cl.getName());
        out.writeString(obj.toString());
        out.writeMapEnd();

    }
}

-------------------

package com.aebn.media.util.hessian;

import com.caucho.hessian.io.AbstractDeserializer;
import com.caucho.hessian.io.AbstractHessianInput;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;

/**
 * De-serializes Java 1.5 enumerations.
 *
 * @author kp
 */
public class JavaEnumDeSerializer extends AbstractDeserializer {

    private static Log LOG = LogFactory.getLog(JavaEnumDeSerializer.class);

    public Object readMap(AbstractHessianInput in) throws IOException {

        String clazz = null;
        String value = null;

        while (! in.isEnd()) {
          clazz = in.readString();
          value = in.readString();
        }
        in.readMapEnd();

        if (clazz == null)
            throw new IOException("Expected Enum class name");
        if (value == null)
            throw new IOException("Expected Enum class value");

        if (LOG.isDebugEnabled())
            LOG.debug("Reading enum of type " + clazz + " with value: " +
value);

        Class enumClazz = null;
        try {
            enumClazz = Class.forName(clazz);
        } catch (ClassNotFoundException e) {
            throw new IOException("Expected Enum class (" + clazz + ") was
not found");
        }

        return (Enum.valueOf(enumClazz, value));
    }

}

-----Original Message-----
From: owner-hessian-interest@xxx.com
[mailto:owner-hessian-interest@xxx.com]On Behalf Of Andrus Adamchik
Sent: Tuesday, October 25, 2005 2:23 AM
To: hessian-interest@xxx.com
Subject: Enums and other serialization woes

Hi folks,

I am using Hessian as the main transport mechanism for the new remote
features developed for Cayenne persistence framework (http://
objectstyle.org/cayenne). It worked very well so far, with (de)
serialization oddities being the only headache. I've been able to
resolve most issues up till now, but this time I figured I'd ask for
the insights from the community.

This is regarding passing of JDK 1.5 enums over the wire (there were
a few threads about enums on this list, but nothing I can use as a
guidance). Of course it would be nice to have enums supported by
Hessian out of the box, but I figured I'd create a workaround until
this happens. The first approach was to use readResolve/writeReplace
on an Enum class. It works for a standalone enum objects, but breaks
if enum is a field of another object. With hessian-3.0.13 I get the
following stack:

java.lang.IllegalArgumentException: Cannot reflectively create enum
objects
     at java.lang.reflect.Constructor.newInstance(Constructor.java:492)
     at com.caucho.hessian.io.JavaDeserializer.instantiate
(JavaDeserializer.java:199)
     at com.caucho.hessian.io.JavaDeserializer.readMap
(JavaDeserializer.java:105)
     at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java)
     at com.caucho.hessian.io.JavaDeserializer.readMap
(JavaDeserializer.java:150)
     at com.caucho.hessian.io.JavaDeserializer.readMap
(JavaDeserializer.java:107)
     at com.caucho.hessian.io.SerializerFactory.readMap
(SerializerFactory.java)
     at com.caucho.hessian.io.HessianInput.readObject
(HessianInput.java:1126)

(I guess I need to log a bug report with more details)

Second, I figured I'd roll my own serializers, which was pretty
trivial. But registering custom serializers seem to require
subclassing on HessianProxyFactory (on the client end) and
HessianServlet (on the server end). I was wondering if there is an
easier, less intrusive way to achieve that?

Thanks
Andrus Adamchik
Received on Tue 25 Oct 2005 07:39:39 -0700

This archive was generated by hypermail 2.1.8 : Thu Sep 28 2006 - 20:16:41 PDT