JDK-6988254 : Serialization of enums is broken while using IIOP
  • Type: Bug
  • Component: other-libs
  • Sub-Component: corba:idl
  • Affected Version: 6u21
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: linux
  • CPU: x86
  • Submitted: 2010-09-29
  • Updated: 2014-04-10
  • Resolved: 2014-04-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7-poolResolved
Related Reports
Relates :  
Description
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