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