JDK-4916752 : Wrong discriminator received on a union with multiple case labels on a branch
  • Type: Bug
  • Component: other-libs
  • Sub-Component: corba:idl
  • Affected Version: 1.4.2
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_nt
  • CPU: generic
  • Submitted: 2003-09-03
  • Updated: 2009-06-25
  • Resolved: 2004-12-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 Availabitlity Release.

To download the current JDK release, click here.
Other
1.4.1 07Fixed
Description
Customer problem description:

>synopsis:    wrong discriminator received on a union with multiple case 
>labels on a branch
>description: FULL PRODUCT VERSION :
>java version "1.4.2_01"
>Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_01-b06)
>Java HotSpot(TM) Client VM (build 1.4.2_01-b06, mixed mode)
>
>
>FULL OS VERSION :
>Windows NT Version 4.0
>
>
>A DESCRIPTION OF THE PROBLEM :
>Consider this IDL union with a branch that has multiple case labels.


// Multiple case labels per member.
// ================================================================
union U switch(long)
{
 case 1:
 case 2:
   long longer;
 default:
   short shot;
};


// Interfaces
// ================================================================

interface Simple
{
    void   testmcls(inout U u);
};

interface SimpleFactory
{
    Simple find_simple();
};

>
>In either client or server, select the "longer" branch, setting the
>discriminator to 2.  Now pass the union to the other side, and examine
>it: the discriminator value is 1.
>
>Here's a swatch of the UHelper.read() code generated by idlj:
>
>   public static U read (org.omg.CORBA.portable.InputStream istream)
>   {
>     U value = new U ();
>     int _dis0 = (int)0;
>     _dis0 = istream.read_long ();
>     switch (_dis0)
>     {
>       case 1:
>       case 2:
>         int _longer = (int)0;
>         _longer = istream.read_long ();
>         value.longer (_longer);
>         break;
>
>Shouldn't it be doing this instead?
>
>         value.longer (_dis0, _longer);

UHelper.write() is sending the union's discriminator
correctly, but UHelper.read() isn't selecting the union's "longer"
branch with the discriminator _dis0 that it had just read.

The same problem also exists in the default branch in UHelper.read().

>
>STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
>Use idlj to generate code.
>Build a CORBA application that passes the union from client to server.
>Select the "longer" union member, setting the discriminant to 2.
>Pass the union to the other side.
>Examine the discriminator value, which should be 2, but it is 1.
>
>
>EXPECTED VERSUS ACTUAL BEHAVIOR :
>EXPECTED -
>Discriminator value should be 2.
>
>ACTUAL -
>Discriminator value was 1.
>
>
>ERROR MESSAGES/STACK TRACES THAT OCCUR :
>none.
>
>
>REPRODUCIBILITY :
>This bug can be reproduced always.
>

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.4.1_07 1.4.2_04 generic tiger-beta FIXED IN: 1.4.1_07 1.4.2_04 INTEGRATED IN: 1.4.1_07 1.4.2_04 tiger-b31 tiger-b32 VERIFIED IN: 1.4.2_04
2004-06-14

WORK AROUND Hand-edit the generated UHelper.read() method.
2004-06-11

SUGGESTED FIX ------- UnionGen.java ------- *** /tmp/sccs.Y8ai8o Mon Sep 29 14:53:43 2003 --- UnionGen.java Mon Sep 29 14:25:17 2003 *************** *** 736,742 **** if (noCases) { // There is only a default label. Since there are no cases, // there is no need for if...else branches. ! index = readBranch (index, indent, firstBranch.typedef.name (), firstBranch.typedef, stream); } else { // If first branch is false, swap branches if (!firstBranchIsTrue) { --- 736,742 ---- if (noCases) { // There is only a default label. Since there are no cases, // there is no need for if...else branches. ! index = readBranch (index, indent, firstBranch.typedef.name (), "", firstBranch.typedef, stream); } else { // If first branch is false, swap branches if (!firstBranchIsTrue) { *************** *** 752,758 **** else { stream.println (indent + '{'); index = readBranch (index, indent + " ", firstBranch.typedef.name (), ! firstBranch.typedef, stream); stream.println (indent + '}'); } --- 752,758 ---- else { stream.println (indent + '{'); index = readBranch (index, indent + " ", firstBranch.typedef.name (), ! disName, firstBranch.typedef, stream); stream.println (indent + '}'); } *************** *** 763,769 **** else { stream.println (indent + '{'); index = readBranch (index, indent + " ", secondBranch.typedef.name (), ! secondBranch.typedef, stream); stream.println (indent + '}'); } } --- 763,769 ---- else { stream.println (indent + '{'); index = readBranch (index, indent + " ", secondBranch.typedef.name (), ! disName, secondBranch.typedef, stream); stream.println (indent + '}'); } } *************** *** 801,807 **** if (!branch.typedef.equals (u.defaultBranch ())) { index = readBranch (index, indent + " ", branch.typedef.name (), ! branch.typedef, stream); stream.println (indent + " break;"); } } --- 801,807 ---- if (!branch.typedef.equals (u.defaultBranch ())) { index = readBranch (index, indent + " ", branch.typedef.name (), ! disName, branch.typedef, stream); stream.println (indent + " break;"); } } *************** *** 817,823 **** stream.println( indent + " value._default( " + disName + " ) ;" ) ; } else { index = readBranch (index, indent + " ", u.defaultBranch ().name (), ! u.defaultBranch (), stream); } stream.println (indent + " break;"); --- 817,823 ---- stream.println( indent + " value._default( " + disName + " ) ;" ) ; } else { index = readBranch (index, indent + " ", u.defaultBranch ().name (), ! "", u.defaultBranch (), stream); } stream.println (indent + " break;"); *************** *** 828,834 **** return index; } ! private int readBranch (int index, String indent, String name, TypedefEntry entry, PrintWriter stream) { SymtabEntry type = entry.type (); Util.writeInitializer (indent, '_' + name, "", entry, stream); --- 828,834 ---- return index; } ! private int readBranch (int index, String indent, String name, String disName, TypedefEntry entry, PrintWriter stream) { SymtabEntry type = entry.type (); Util.writeInitializer (indent, '_' + name, "", entry, stream); *************** *** 842,849 **** stream.println (indent + '_' + name + " = " + Util.helperName (type, true) + ".read (istream);"); } ! stream.println (indent + "value." + name + " (_" + name + ");"); ! return index; } --- 842,852 ---- stream.println (indent + '_' + name + " = " + Util.helperName (type, true) + ".read (istream);"); } ! stream.print (indent + "value." + name + " ("); ! if( disName == "" ) ! stream.println("_" + name + ");"); ! else ! stream.println(disName + ", " + "_" + name + ");"); return index; } ###@###.### 2003-09-29 The above fix caused default setter without setting value with corresponding discriminator. new fix URL: http://jpsesvr.sfbay.sun.com:8080/ctetools/html/ViewDetail.jsp?index=821 ###@###.### 2003-10-08
2003-10-08

EVALUATION In src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/UnionGen.java: function readBranch did not output the discriminator string. We need to change it to have the output have this part. See Suggested Fix. ###@###.### 2003-09-29
2003-09-29