Issue 10336: Section: 1.3, Page: 1-21 (java2idl-rtf) Source: (, ) Nature: Enhancement Severity: Critical Summary: Java to IDL Language Mapping Specification doesn't cover the mapping for Java enum from JDK 1.5. We propose the following mapping to be included in the specification. Mapping for Enumeration: When used as a parameter, return type or member variable, Java enum in JDK 1.5 is mapped to the OMG IDL type ::javax::rmi::CORBA::EnumDesc. The corresponding representation in Java class is: package javax.rmi.CORBA; public class EnumDesc implements java.io.Serializable { // Holds the value of enum public String value; // Name of enum class public String className; static final long serialVersionUID = ...; } The mapping in IDL will be: module javax { module rmi { module CORBA { valuetype EnumDesc { public ::CORBA::WStringValue value; #pragma ID value "RMI:EnumDesc/value:xxxxx" public ::CORBA::WStringValue className; #pragma ID className "RMI:EnumDesc/className:xxxxx" }; #pragma ID EnumDesc "RMI:EnumDesc:aaaaaa:xxxxxxxxx" }; }; }; Resolution: Revised Text: In section 1.3.5: ----------------- Change ... and java.lang.Class (see Section 1.3.5.12, “Mapping for java.lang.Class,” on page 1-21). to ..., java.lang.Class (see Section 1.3.5.12, “Mapping for java.lang.Class,” on page 1-21), java.lang.Enum (see Section 1.3.5.13, “Mapping for java.lang.Enum,” on page 1-xx), and all Java enum types (see Section 1.3.5.14, “Mapping for Java enum types,” on page 1-xx). Add new section 1.3.5.13: ------------------------- Mapping for java.lang.Enum The class java.lang.Enum is mapped to OMG IDL following the rules for mapping RMI/IDL value types defined in previous sections, with the exception that the ordinal field is not mapped to an OMG IDL data member. For example, this class could be mapped to the following OMG IDL: // IDL module java { module lang { valuetype _Enum: ::java::lang::Comparable { private ::CORBA::WStringValue name_; ::CORBA::WStringValue name( ); }; #pragma ID _Enum "RMI:java.lang.Enum:CA9967EE1176F5B3:0000000000000000" }; }; Add new section 1.3.5.14: ------------------------- Mapping for Java enum types Java enum types are mapped to OMG IDL following the rules for mapping RMI/IDL value types defined in previous sections, with the exception that their fields are not mapped to OMG IDL data members. For example, the Java enum public enum Direction { NORTH (0), SOUTH (180), EAST (90), WEST (270); public final int bearing; Direction(int bearing) { this.bearing = bearing; } } could be mapped to the following OMG IDL: // IDL valuetype Direction: ::java::lang::_Enum { }; #pragma ID Direction "RMI:Direction:332C04E72E3DB2A1:0000000000000000" Changes to section 1.5.1.5 -------------------------- At the end of the description of the readValue method, add the following: If clz is an enum class, readValue returns the singleton enum constant that is the result of calling the java.lang.Enum.valueOf() method passing clz and the string name of the enum constant unmarshaled from the mapped enum valuetype in the stream. At the end of the description of the getRMIRepositoryID method, add the following: If clz is an anonymous class for an enum constant with a class body (i.e., its superclass is not java.lang.Enum), then the getRMIRepositoryID method returns the RMI-style repository ID string for the named superclass of clz. Actions taken: September 5, 2006: received issue July 30, 2007: closed issue Discussion: Resolution: Closed, accepted. See revised text below End of Annotations:===== m: webmaster@omg.org Date: 05 Sep 2006 02:31:24 -0400 To: Subject: Issue/Bug Report -------------------------------------------------------------------------------- Name: Naveed Shaikh Company: Borland mailFrom: naveed.shaikh@borland.com Notification: Yes Specification: Java to IDL Language Mapping Section: 1.3 FormalNumber: formal/03-09-04 Version: 1.3 RevisionDate: 09/01/03 Page: 1-21 Nature: Enhancement Severity: Critical HTTP User Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322) Description Java to IDL Language Mapping Specification doesn't cover the mapping for Java enum from JDK 1.5. We propose the following mapping to be included in the specification. Mapping for Enumeration: When used as a parameter, return type or member variable, Java enum in JDK 1.5 is mapped to the OMG IDL type ::javax::rmi::CORBA::EnumDesc. The corresponding representation in Java class is: package javax.rmi.CORBA; public class EnumDesc implements java.io.Serializable { // Holds the value of enum public String value; // Name of enum class public String className; static final long serialVersionUID = ...; } The mapping in IDL will be: module javax { module rmi { module CORBA { valuetype EnumDesc { public ::CORBA::WStringValue value; #pragma ID value "RMI:EnumDesc/value:xxxxx" public ::CORBA::WStringValue className; #pragma ID className "RMI:EnumDesc/className:xxxxx" }; #pragma ID EnumDesc "RMI:EnumDesc:aaaaaa:xxxxxxxxx" }; }; }; Date: Tue, 19 Sep 2006 18:02:02 +0100 From: Simon Nash Organization: IBM User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en To: naveed.shaikh@borland.com CC: java2idl-rtf@omg.org Subject: Re: issue 10336 -- Java to IDL RTF issue Naveed, I agree that we should have a mapping for the Java enum type, but I'm a bit puzzled by this proposal. Why not simply map the Java enum type to the OMG IDL enum type? Is there some problem with doing this? Simon Juergen Boldt wrote: From: webmaster@omg.org Date: 05 Sep 2006 02:31:24 -0400 To: Subject: Issue/Bug Report ------------------------------------------------------------------------ * Name: Naveed Shaikh * Company: Borland * mailFrom: naveed.shaikh@borland.com * Notification: Yes * Specification: Java to IDL Language Mapping * Section: 1.3 * FormalNumber: formal/03-09-04 * Version: 1.3 * RevisionDate: 09/01/03 * Page: 1-21 * Nature: Enhancement * Severity: Critical * HTTP User Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322) Description Java to IDL Language Mapping Specification doesn't cover the mapping for Java enum from JDK 1.5. We propose the following mapping to be included in the specification. Mapping for Enumeration: When used as a parameter, return type or member variable, Java enum in JDK 1.5 is mapped to the OMG IDL type ::javax::rmi::CORBA::EnumDesc. The corresponding representation in Java class is: package javax.rmi.CORBA; public class EnumDesc implements java.io.Serializable { // Holds the value of enum public String value; // Name of enum class public String className; static final long serialVersionUID = ...; } The mapping in IDL will be: module javax { module rmi { module CORBA { valuetype EnumDesc { public ::CORBA::WStringValue value; #pragma ID value "RMI:EnumDesc/value:xxxxx" public ::CORBA::WStringValue className; #pragma ID className "RMI:EnumDesc/className:xxxxx" }; #pragma ID EnumDesc "RMI:EnumDesc:aaaaaa:xxxxxxxxx" }; }; }; Juergen Boldt Director, Member Services Object Management Group 140 Kendrick St Building A Suite 300 Needham, MA 02494 USA tel: +1 781 444 0404 x 132 fax: +1 781 444 0320 email: juergen@omg.org www.omg.org -- Simon C Nash IBM Distinguished Engineer Hursley Park, Winchester, UK nash@hursley.ibm.com Tel. +44-1962-815156 Fax +44-1962-818999 Subject: RE: issue 10336 -- Java to IDL RTF issue Date: Wed, 20 Sep 2006 14:47:43 +0800 X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: issue 10336 -- Java to IDL RTF issue Thread-Index: AcbcDVo37Cwnk6dITdGmA3t+Tro3UAAcnabg From: "Naveed Shaikh" To: "Simon Nash" Cc: X-OriginalArrivalTime: 20 Sep 2006 06:49:51.0396 (UTC) FILETIME=[F8C0FE40:01C6DC80] X-TM-AS-Product-Ver: SMEX-7.0.0.1499-3.6.1039-14702.001 X-TM-AS-Result: No--38.641500-8.000000-31 X-MIME-Autoconverted: from quoted-printable to 8bit by amethyst.omg.org id k8K6maqG009942 Hi Simon, IDL enums are inherently integer-based whereas Java enums are string-based. IDL enums are marshalled as integers. Mapping Java enum to integer will require sending ordinal of enumeration constant during marshalling and using the same ordinal to create back Java enum on the receiving side. Problem is that enum class (java.lang.Enum) doesn't provide a direct way to get Java enum instance from the ordinal itself. Also serialized representation of Java enum is its string value (name) not the integer (ordinal). If integer is used for representing marshalled Java enum, the possible way to do successful unmarshalling could be to iterate through the list of constants (using static method - values()?) in the marshalled enum class making ordinal-based comparison. This approach looks cumbersome. The idea of using javax.rmi.CORBA.EnumDesc is to avoid this issue and also to be close to the natural representation of serialized Java enum. Naveed -----Original Message----- From: Simon Nash [mailto:nash@hursley.ibm.com] Sent: Wednesday, September 20, 2006 1:02 AM To: Naveed Shaikh Cc: java2idl-rtf@omg.org Subject: Re: issue 10336 -- Java to IDL RTF issue Naveed, I agree that we should have a mapping for the Java enum type, but I'm a bit puzzled by this proposal. Why not simply map the Java enum type to the OMG IDL enum type? Is there some problem with doing this? Simon Juergen Boldt wrote: > >> From: webmaster@omg.org >> Date: 05 Sep 2006 02:31:24 -0400 >> To: >> Subject: Issue/Bug Report >> >> --------------------------------------------------------------------- >> --- >> >> * Name: Naveed Shaikh >> * Company: Borland >> * mailFrom: naveed.shaikh@borland.com >> * Notification: Yes >> * Specification: Java to IDL Language Mapping >> * Section: 1.3 >> * FormalNumber: formal/03-09-04 >> * Version: 1.3 >> * RevisionDate: 09/01/03 >> * Page: 1-21 >> * Nature: Enhancement >> * Severity: Critical >> * HTTP User Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT >> 5.1; .NET CLR 1.1.4322) >> >> >> Description >> >> >> >> Java to IDL Language Mapping Specification doesn't cover the mapping >> for Java enum from JDK 1.5. We propose the following mapping to be >> included in the specification. Mapping for Enumeration: When used as >> a parameter, return type or member variable, Java enum in JDK 1.5 is >> mapped to the OMG IDL type ::javax::rmi::CORBA::EnumDesc. The >> corresponding representation in Java class is: package >> javax.rmi.CORBA; public class EnumDesc implements >> java.io.Serializable { // Holds the value of enum public String >> value; // Name of enum class public String className; static final >> long serialVersionUID = ...; } The mapping in IDL will be: module >> javax { module rmi { module CORBA { valuetype EnumDesc { public >> ::CORBA::WStringValue value; #pragma ID value >> "RMI:EnumDesc/value:xxxxx" public ::CORBA::WStringValue className; >> #pragma ID className "RMI:EnumDesc/className:xxxxx" }; #pragma ID >> EnumDesc "RMI:EnumDesc:aaaaaa:xxxxxxxxx" }; }; }; > > > Juergen Boldt > Director, Member Services > Object Management Group > 140 Kendrick St > Building A Suite 300 > Needham, MA 02494 > USA > > tel: +1 781 444 0404 x 132 > fax: +1 781 444 0320 > email: juergen@omg.org > www.omg.org > -- Simon C Nash IBM Distinguished Engineer Hursley Park, Winchester, UK nash@hursley.ibm.com Tel. +44-1962-815156 Fax +44-1962-818999 Date: Thu, 28 Sep 2006 13:08:02 +0100 From: Simon Nash Organization: IBM User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en To: Ken Cavanaugh CC: Naveed Shaikh , java2idl-rtf@omg.org, corba-dev , Marina Vatkina , chackoj@uk.ibm.com Subject: Re: issue 10336 -- Java to IDL RTF issue (WARNING - LONG EMAIL) Ken, Yes, we definitely need to think about how we can preserve interoperability when we fix this problem. I have been thinking about this issue and I have come up with 3 possible options. I'll summarize them first, then expand on the pros and cons of each of them. 1. Naveed's proposal (with a couple of minor refinements) Pro: Easy to implement in Java Follows Java serialization treatment of enum types Con: Does not work well for languages other than Java Not interoperable with ORBs that don't have the fix 2. Map Java enums to IDL enums Pro: very simple and efficient Con: Does not support the full semantics of Java enums Not interoperable with ORBs that don't have the fix 3. Use current mapping with "receiver makes right" Pro: Interoperable with ORBs that don't have the fix Works well for languages other than Java Con: Not as easy to implement in Java as option 1 - - - - - - - - - - - OPTION 1 As Ken points out, this is easy to implement in Java by using Enum.valueOf() when unmarshaling the proposed CDR encoding. If we adopt this approach, then I would suggest the following refinements to the original proposal: 1. Sending the enum class information as a String class name is not sufficient for the receiver to fully resolve this to the correct Class object in all cases. This problem can be solved by representing the class information as a Class object, which will be marshaled as ::javax::rmi::CORBA::ClassDesc (similar to the format used by Java serialization of enum types). 2. The IDL mapping in the proposal is not quite what the Sun rmic compiler generates. In particular, the generated code does not include the #pragma ID directives for "value" and "className" that you have in your proposal. I cannot see anything in the Java to IDL mapping spec that implies that these #pragma ID directives should be generated. Rather than including specific IDL in the specification, I think it's better to do what we did for javax.rmi.CORBA.ClassDesc and say that the generated IDL is the result of mapping the javax.rmi.CORBA.EnumDesc class. Unfortunately this approach doesn't interoperate with current ORBs because current ORBs won't have the javax.rmi.CORBA.EnumDesc class and therefore will be unable to unmarshal the CDR representation produced by an ORB that does have the fix. Similarly an ORB with the fix won't be able to correctly unmarshal enums that were marshaled by an ORB without the fix. These will continue to be unmarshaled as new instances, as they are at present. Also, this representation isn't very good for unmarshaling by non-Java ORBs. Java enums are very sophisticated and can contain arbitrary data as well as the string name of the enum constant. The proposal doesn't allow this arbitrary data to be marshaled. An example is the Planet class that appears in the JDK5 document describing enums. The double values for "mass" and "radius" of the various planets won't be marshaled, only the planet names. For a Java receiver, this doesn't matter, because the Planet class will be available to provide this information and the Enum.valueOf() method will return a Planet enum constant containing the correct mass and radius values. However, a non-Java receiver won't have the Java Planet class implementation available, so it would need to provide its own implementation definitions for the mass and radius values of all the Java Planet constants. This could be done, but it's awkward and error-prone compared with having these data values transmitted on the wire as an integral part of the Java enum constant. - - - - - - - - - - - OPTION 2 This is a non-starter for various reasons, as already pointed out by Ken and Naveed. It only transmits a 32-bit ordinal number for each enum constant, and there's no convenient Java API that can be used by a Java receiver to reconstruct the correct enum constant from this information. There are also versioning issues when new members are added to the set of enum constants (not a problem if string names are marshaled); there's the problem of non-interoperability with current ORBs; and there's the same inability to transmit enum constant data that was a disadvantage of option 1. - - - - - - - - - - - OPTION 3 With this approach, enum constants would continue to be marshaled as CORBA valuetypes. The change is in how a Java unmarshaler treats them. Instead of creating a new instance as at present, it would extract the class information and enum constant name string (both of which are carried in the current valuetype encoding) and call Enum.valueOf() to return the correct enum constant. Non-Java ummarshalers would continue to return a new valuetype instance containing the correct data values matching those on the Java side. This approach is interoperable with current ORBs, since the on-the-wire representation doesn't change. ORBs with the fix return the correct enum constant, and ORBs without the fix return a new instance as they do currently. There's no need for non-Java receivers to know the data values for all the Java enum constants, as this information is included in the on-the-wire representation. The only disadvantage is slightly more complex Java unmarshaling code to recognize the case of a valuetype that is a subtype of Enum, and perform special-case unmarshaling to call Enum.valueOf(). - - - - - - - - - - - Are others in agreement with these pros and cons of the various options? Are there any other options that we could consider? Simon Ken Cavanaugh wrote: I'd like to get started on serious discussion about the proposed fix for this issue as soon as possible (probably after this week's Anaheim meeting?). This issue has come up repeatedly for Sun in both Java SE and Java EE, so I think we are seeing enough customer impact that we should start working on the issue in this RTF. I do have one question for the proposal: has anyone considered what the impact of the proposed changes are for interoperability with ORBs that do not have the fix? Thanks, Ken. -- Simon C Nash IBM Distinguished Engineer Hursley Park, Winchester, UK nash@hursley.ibm.com Tel. +44-1962-815156 Fax +44-1962-818999 Date: Mon, 09 Oct 2006 02:01:30 +0100 From: Simon Nash Organization: IBM User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en To: Bob.Scheifler@sun.com CC: Ken Cavanaugh , Naveed Shaikh , java2idl-rtf@omg.org, corba-dev , Marina Vatkina , chackoj@uk.ibm.com Subject: Re: issue 10336 -- Java to IDL RTF issue Sorry for the delay in responding to the various points made by Ken and Bob. I have been thinking hard about the issues raised by Bob about option 3, and I think there is a variation of this approach that works a lot better. Before I describe this, I'd like to respond to the suggestion that the current behavior of the Sun ORB is the unspecified behavior of one implementation. It seems to me that the mapping rules in the current specification require that enum types with serializable fields are mapped to valuetypes following the normal algorithm, and that enum types with non-serializable fields are mapped to abstract valuetypes (section 1.3.10) and throw an exception if serialized. Clearly this is wrong, but I believe it's what the spec currently says. I think the place where unspecified implementation behavior does come into play is in the unmarshaling of a valuetype that resulted from mapping java.lang.Enum under the current rules. The creation of a new instance of the enum class that is distinct from any of the defined values should not be possible in any circusmtances, because it creates the security hole described by Bob. So the fix to this issue should specify an unmarshaling of valuetypes derived from java.lang.Enum that closes this security hole. It's not sufficient to just create a new format for how enums are marshaled (as in option 1), because ORBs could still receive the current enum/valuetype marhsaled format in an input stream that was constructed either by an ORB with the bug or by malicious hand-crafted code. Now back to the options, and how to deal with the issues raised. Enums with non-serializable fields look like a showstopper for option 3, so I'd like to suggest a new option 4 (a modification of option 3) that does handle enums with non-serializable fields. Option 4 is like option 3 in that the mapping is still a valuetype corresponding to the enum class, and the unmarshaling code for valuetypes checks for valuetypes that are derived from java.lang.Enum and constructs an Enum constant using Enum.valueOf(). It differs from option 3 in the rules for mapping the enum fields. In option 4, no fields defined by the enum type are mapped to IDL. (The fields of the abstract base class java.lang.Enum are still mapped.) Also, the SUID in the repid for enum types is set to 0L for consistency with Java5 serialization. Option 4 has a number of advantages over options 1 and 3: - unlike option 1, the new unmarshaling code can read valuetypes serialized by current ORBs because the new format is a compatible subset of the current format. (The unmarshaler just ignores any enum fields and the non-zero SUID.) - unlike option 3, it supports enums with non-serializable fields. Since no enum fields are mapped to IDL, it doesn't matter whether the fields are serializable or non-serializable. - unlike option 3 or option 1, the unmarshaling code in current ORBs fails cleanly when an enum marshaled by an ORB with the fix is unmarshaled by a current ORB. This is because the SUID sent on the wire by new ORBs with the fix is 0L, which is incompatible with the value computed by current ORBs. With option 3, current ORBs would still unmarshal an enum that was serialized by an ORB with the fix, creating a security hole. With option 1, the format has changed incompatibly and a current ORB unmarshaling the new format (or vice versa) would read garbage from the stream and could fail in unpredictable ways or perhaps even unmarshal a bogus value. - unlike option 1, it closes the unmarshaling security hole that allows incorrect enum instances to be unmarshaled from the currently serialized valuetype form. Unless I have missed something in the above (quite possible , it seems that option 4 has quite a few advantages over any of the other alternatives. The only disadvantage of option 4 that I can think of is that it does not serialize any enum fields on the wire and so could require more code to be written when interoperating with other languages (as does option 1). To alleviate this, we could consider an option 4a that is like option 4 except that it maps serializable fields of enum types to IDL, but does not map non-serialiable fields. Option 4a has all the advantages of option 4 that were described above. The main difference is what data travels on the wire. With option 4, the data that travels on the wire is the class identification, the enum constant name, and the enum constant ordinal. With option 4a, the serializable enum fields also travel on the wire for possible use for non-Java interoperability, though they are not used by Java unmarshaling. It seems to me that the extra complexity of 4a over 4 is not justified. The mapping rules are more complex and the wire format contains data that is redundant from a Java perspective. Option 4 does not prevent cross-language interoperability. Although it might require more C++ code to be written in some cases (probably fairly rare), this is offset by the complexity in option 4a of having a different unmarshaling approach in C++ (using different on-the-wire data) compared with Java. Option 4 is simple to explain, and unmarshaling in both Java and C++ use the same wire data and work the same way. So from my perspective it seems that option 4 is the best of the alternatives, unless there are other variants that I haven't considered. What do others think? Simon -- Simon C Nash IBM Distinguished Engineer Hursley Park, Winchester, UK nash@hursley.ibm.com Tel. +44-1962-815156 Fax +44-1962-818999 Date: Mon, 09 Oct 2006 23:49:48 +0100 From: Simon Nash Organization: IBM User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en To: Bob.Scheifler@sun.com CC: Ken Cavanaugh , Naveed Shaikh , java2idl-rtf@omg.org, corba-dev , Marina Vatkina , chackoj@uk.ibm.com Subject: Re: issue 10336 -- Java to IDL RTF issue Bob, The ordinal field of Enum is included as a consequence of following the normal Java to IDL mapping rules for the Enum class. It is not used in unmarshaling. We could write a special rule excluding it from the mapping, but this seems like more complexity and special case treatment than is warranted in order to save 4 bytes. If the ordinal field were to be declared as transient, this would prevent it from being mapped to IDL and marshaled on the wire. Is there any chance of gettng this change into Java6? I had not considered the case of enum constants with class bodies. We would need to add something to the Java to IDL mapping spec to allow for these. I believe the required change is in section 1.5.1.5, the first paragraph under the subheading ValueMarshaling. The current text is as follows: When marshaling an RMI value, the ORB stream must call Util.getCodeBase to get the codebase string, ValueHandler.getRMIRepositoryID to get the repository ID string, and ValueHandler.isCustomMarshaled to see if the value is custom marshaled and therefore requires a chunked encoding. I think we need to add the following at the end of this paragraph: For RMI values that are enum constants with class bodies, the Class object clz passed to ValueHandler.getRMIRepositoryID must be the enum class, not the actual class of the enum constant. This raises the question of how the ValueHandler should test for this case in its writeValue method. What's the easiest way to determine whether the value passed to writeValue is an enum constant with an anonymous class? As you say, this slightly complicates the interoperability story with current ORBs. For this case, current ORBs will produce an on-the-wire format that can't be unmarshaled by an ORB with the fix because of the class name mismatch. I'm inclined to let this case fall by the wayside and fail with a "class not found" error rather than defining a special fix-up rule to make it work. In the opposite direction, we get the same unmarshaling failure that we would with any other enum constant because of the zero/nonzero SUID mismatch, avoiding the security hole. Simon Bob Scheifler wrote: Option 4 is like option 3 in that the mapping is still a valuetype corresponding to the enum class, and the unmarshaling code for valuetypes checks for valuetypes that are derived from java.lang.Enum and constructs an Enum constant using Enum.valueOf(). It differs from option 3 in the rules for mapping the enum fields. In option 4, no fields defined by the enum type are mapped to IDL. (The fields of the abstract base class java.lang.Enum are still mapped.) Also, the SUID in the repid for enum types is set to 0L for consistency with Java5 serialization. Why are you including the ordinal field of Enum on the wire? Is it always ignored by the receiver? An issue that I don't think has been made explicit is that an enum constant with a class body will be an instance of an anonymous subclass of the enum class. In that case, the class descriptor on the wire must be the superclass (which is the enum class), not the anonymous class. (This will present another interoperability impact with existing ORBs.) - Bob -- Simon C Nash IBM Distinguished Engineer Hursley Park, Winchester, UK nash@hursley.ibm.com Tel. +44-1962-815156 Fax +44-1962-818999 Date: Tue, 10 Oct 2006 18:55:19 +0100 From: Simon Nash Organization: IBM User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en To: Bob.Scheifler@sun.com CC: Ken Cavanaugh , Naveed Shaikh , java2idl-rtf@omg.org, corba-dev , Marina Vatkina , chackoj@uk.ibm.com Subject: Re: issue 10336 -- Java to IDL RTF issue Bob, I think there is a considerable difference between a) defining a special mapping for enum classes (those defined using "enum EnumName" rather than "class ClassName"), and b) changing the mapping of a regular J2SE class such as java.lang.Enum. Currently RMI-IIOP uses the J2SE5-defined serialized form for all J2SE classes, except for a small number of classes that are called out in the spec as specific exceptions to this rule. I think we need a stronger reason than saving 4 bytes (which are apparently redundant) in order to deviate from the normal rules for class mapping. Apart from this philosophical design preference, here are some practical reasons why it may not be good to create a special mapping for the java.lang.Enum class. 1. The ordinal is a documented part of the serialized form for java.lang.Enum. The reason given for including it is for use by sophisticated enum-based data structures, such as EnumSet and EnumMap. Presumably this field might be needed when marshaling these enum-based data structures over RMI-IIOP. 2. Omitting the ordinal field from the serialized form could cause problems with interoperating with current ORBs without the fix. With option 4 as currently proposed, the mapping for the java.lang.Enum base class does not change, although the mapping of the enum-specific subclass does. It is possible that a change to the format of the base class might cause additional glitches in the interoperability story for this case. 3. If the serialized form of the java.lang.Enum class ever changes in the future, we might need to adjust the special mapping and put in place additional mechanisms to ensure interoperabilty. Currently we can just use the normal class evolution mechanisms of SendingContextRunTime and FullValueDescription to handle this situation. Regarding the precise error when unmarshaling an enum constant whose repid indicates an anonymous class, I understand that there is a possibility of the unmarshaling accidentally succeeding. However, I don't see any way to ensure that this doesn't happen. Since the name of the anonymous class is determined by the sending implementation, I can't think of any way that the receiver can reliably detect this case and force an error. Simon Bob Scheifler wrote: The ordinal field of Enum is included as a consequence of following the normal Java to IDL mapping rules for the Enum class. It is not used in unmarshaling. We could write a special rule excluding it from the mapping, but this seems like more complexity and special case treatment than is warranted in order to save 4 bytes. You're going to need special language to cover the enum mapping anyway, and special implementation code. Seems better to me to do it right and elide the ordinal. If the ordinal field were to be declared as transient, this would prevent it from being mapped to IDL and marshaled on the wire. Is there any chance of gettng this change into Java6? Beats me, but the justification seems quite weak. What's the easiest way to determine whether the value passed to writeValue is an enum constant with an anonymous class? If the superclass is not java.lang.Enum, then the superclass is the enum class. I'm inclined to let this case fall by the wayside and fail with a "class not found" error rather than defining a special fix-up rule to make it work. Note that you may not get "class not found", it may in fact resolve to a class, and may resolve to the wrong class (since in theory the generation of anonymous class names is implementation dependent). - Bob -- Simon C Nash IBM Distinguished Engineer Hursley Park, Winchester, UK nash@hursley.ibm.com Tel. +44-1962-815156 Fax +44-1962-818999 Date: Tue, 10 Oct 2006 20:58:54 +0100 From: Simon Nash Organization: IBM User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en To: Bob.Scheifler@sun.com CC: Ken Cavanaugh , Naveed Shaikh , java2idl-rtf@omg.org, corba-dev , Marina Vatkina , chackoj@uk.ibm.com Subject: Re: issue 10336 -- Java to IDL RTF issue Bob, Thanks for the pointer to this bug report. Apparently I have been taking the information in the javadoc more literally than I should have done. I see that the proposed fix of marking the ordinal field as transient (great suggestion was proposed in July 2004 and there has been no update to this bug report since then. It would be good to know if Sun does plan to adopt this proposed fix. If it could be confirmed that this will happen, then I would agree with you that we should do the same thing in the Java to IDL mapping. Simon Bob Scheifler wrote: I think there is a considerable difference between a) defining a special mapping for enum classes (those defined using "enum EnumName" rather than "class ClassName"), and b) changing the mapping of a regular J2SE class such as java.lang.Enum. The mapping of Enum is only needed because you're propsing to include it as part of a), so I think you're splitting hairs in the end. 1. The ordinal is a documented part of the serialized form for java.lang.Enum. If you mean it's in the generated javadoc, that's considered a bug (5075463), which I see the proposed solution to is to mark the ordinal as transient. It's clearly not part of the serialized form as defined by normal object serialization. The reason given for including it is for use by sophisticated enum-based data structures, such as EnumSet and EnumMap. Presumably this field might be needed when marshaling these enum-based data structures over RMI-IIOP. The ordinal is subject to change during class evolution. It is a property of the declaring class, so the value in the sender is irrelevant, the declaration order in the receiver is what matters. 2. Omitting the ordinal field from the serialized form could cause problems with interoperating with current ORBs without the fix. Your proposed interoperability is only in one direction anyway, which to me seems of rather limited value. 3. If the serialized form of the java.lang.Enum class ever changes in the future It should be clear from how normal object serialization is done that the Enum class doesn't have a serialized form as such. - Bob -- Simon C Nash IBM Distinguished Engineer Hursley Park, Winchester, UK nash@hursley.ibm.com Tel. +44-1962-815156 Fax +44-1962-818999