FULL PRODUCT VERSION :
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
Linux 2.6.32-24-generic #43-Ubuntu SMP Thu Sep 16 14:58:24 UTC 2010 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The serialization of enums is completely broken while using RMI with IIOP. When trying to deserialize an enum (see example-code below) an exception is thrown.
Until JDK 1.6.0_18 I could overwrite the writeReplace() and readResolve() methods of the enum and could use this as workaround for the serialization. Since JDK 1.6.0_19 those methods aren't called anymore so my workaround doesn't work anymore.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
javac EnumIIOPBreakage.java
rmic -classpath . -iiop Server
orbd -ORBInitialPort 1050 (do that in a seperate console)
java -classpath . EnumIIOPBreakage
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Generally:
the serialization of enums should work.
In the Example the following output is expected:
equal?      true
ACTUAL -
none, exception is thrown
ERROR MESSAGES/STACK TRACES THAT OCCUR :
29.09.2010 14:25:31 com.sun.corba.se.impl.encoding.CDRInputStream_1_0 read_value
WARNUNG: "IOP00810211: (MARSHAL) Exception from readValue on ValueHandler in CDRInputStream"
org.omg.CORBA.MARSHAL:   vmcid: SUN  minor code: 211 completed: Maybe
	at com.sun.corba.se.impl.logging.ORBUtilSystemException.valuehandlerReadException(ORBUtilSystemException.java:7004)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:1045)
	at com.sun.corba.se.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:253)
	at _RServer_Stub.getEnum(Unknown Source)
	at EnumIIOPBreakage.main(EnumIIOPBreakage.java:29)
Caused by: java.lang.IllegalArgumentException
	at java.nio.Buffer.position(Buffer.java:218)
	at com.sun.corba.se.impl.encoding.ByteBufferWithInfo.position(ByteBufferWithInfo.java:158)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_2.alignAndCheck(CDRInputStream_1_2.java:77)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_long(CDRInputStream_1_0.java:478)
	at com.sun.corba.se.impl.encoding.CDRInputStream.read_long(CDRInputStream.java:133)
	at com.sun.corba.se.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1002)
	at com.sun.corba.se.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:400)
	at com.sun.corba.se.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:327)
	at com.sun.corba.se.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:293)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:1034)
	... 3 more
Exception in thread "main" java.rmi.MarshalException: CORBA MARSHAL 1398079699 Maybe; nested exception is:
	org.omg.CORBA.MARSHAL:   vmcid: SUN  minor code: 211 completed: Maybe
	at com.sun.corba.se.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:197)
	at javax.rmi.CORBA.Util.mapSystemException(Util.java:67)
	at _RServer_Stub.getEnum(Unknown Source)
	at EnumIIOPBreakage.main(EnumIIOPBreakage.java:29)
Caused by: org.omg.CORBA.MARSHAL:   vmcid: SUN  minor code: 211 completed: Maybe
	at com.sun.corba.se.impl.logging.ORBUtilSystemException.valuehandlerReadException(ORBUtilSystemException.java:7004)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:1045)
	at com.sun.corba.se.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:253)
	... 2 more
Caused by: java.lang.IllegalArgumentException
	at java.nio.Buffer.position(Buffer.java:218)
	at com.sun.corba.se.impl.encoding.ByteBufferWithInfo.position(ByteBufferWithInfo.java:158)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_2.alignAndCheck(CDRInputStream_1_2.java:77)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_long(CDRInputStream_1_0.java:478)
	at com.sun.corba.se.impl.encoding.CDRInputStream.read_long(CDRInputStream.java:133)
	at com.sun.corba.se.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1002)
	at com.sun.corba.se.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:400)
	at com.sun.corba.se.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:327)
	at com.sun.corba.se.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:293)
	at com.sun.corba.se.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:1034)
	... 3 more
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.ObjectStreamException;
import java.rmi.*;
import java.util.*;
import javax.rmi.*;
import javax.naming.*;
enum MyEnum {
    ONE, TWO, THREE;
}
public class EnumIIOPBreakage {
    public static void main(String[] args) throws Throwable {
        
        Hashtable properties = new Hashtable();
        properties.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
        properties.put("java.naming.provider.url", "iiop://localhost:1050");
        new Server(properties);
        Context context = new InitialContext(properties);
        Object ref = context.lookup("server");
        RServer server = (RServer) PortableRemoteObject.narrow(ref, RServer.class);
        server.getEnum(MyEnum.ONE.name());
        System.out.println("equal?         " + "Test".equals(server.getString()));
    }
}
class Server implements RServer {
    public Server(Hashtable properties) throws Throwable {
        PortableRemoteObject.exportObject(this);
        Context context = new InitialContext(properties);
        context.rebind("server", this);
    }
    
    public String getString() {
        return "Test";
    }
    public MyEnum getEnum(String name) {
        return MyEnum.valueOf(name);
    }
}
interface RServer extends Remote {
    public String getString() throws RemoteException;
    MyEnum getEnum(String name) throws RemoteException;
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
none so far