-
Bug
-
Resolution: Fixed
-
P2
-
1.4.0
-
beta2
-
x86
-
linux
-
Not verified
Name: jl125535 Date: 11/07/2002
FULL PRODUCT VERSION :
% java -version
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)
% idlj -version
IDL-to-Java compiler (portable), version "3.1"
FULL OPERATING SYSTEM VERSION :
Linux ganesh2.nt.mel.ot 2.4.7-10 #1 Thu Sep 6 17:27:27 EDT
2001 i686 unknown
ADDITIONAL OPERATING SYSTEMS :
SunOS barney 5.8 Generic_108528-13 sun4u sparc
SUNW,Ultra-Enterprise
A DESCRIPTION OF THE PROBLEM :
This problem breaks interoperability with other ORBs, in
particular it breaks operation with the Iona ORBIX 2000 C++
Orb that is used in a large number of existing applications.
When a GIOP 1.2 Request header is built it adds padding
bytes to the output stream to align the Request Body on an 8
byte boundary as per "CORBA formal 00-11-07 15.4.2.2" which
states in the first paragraph that:
"GIOP 1.2 body must be aligned on an 8 octet boundary."
This is incorrect when there is no Request Body (ie: for
methods with no parameters). "CORBA formal 00-11-07 section
15.4.2.1", last paragraph, states:
"There is no padding after the request header when an
unfragmented request message body is empty."
This also applies to Response headers/bodies.
The problem can be seen in the source of:
com.sun.corba.se.internal.iiop.messages.RequestMessage_1_2
in the method write() (line 158) and also probably in read()
(line 129) since read expects to find the padding in the
input stream.
Similar padding problems can be found in the
ReplyMessage_1_2 class in the same java package.
The padding insertion should either be moved to the code
that writes the Request/Reply body (as generated by the IDL
compiler) or should be implemented in such a way as to be
discarded if a body is not written.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. define an IDL interface that has a method taking no
parameters (see Padding.idl in source code)
2. implement/compile/run a server and client (see source code)
3. Observe packets using a tool such as Ethereal. The method
invocation packets will have extra padding bytes to the next
8 byte boundary (assuming the header doesn't naturally align
itself to that boundary). The current example appends 6
extra bytes.
If you compile the server using the Orbix 2000 java orb
(version 1.2.3) then you will get a marshalling exception
when you run the client.
EXPECTED VERSUS ACTUAL BEHAVIOR :
The following is a full dump of the invocation packet for
the Padding.Pad.pad() method. The last 6 null bytes are the
padding, after the third item in the ServiceContext, to the
next 8 byte boundary (the GIOP packet starts at byte 0x0042
hence the alignment to 0x015a)
0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00
........ ......E.
0010 01 4c c0 21 40 00 40 06 3a 23 0a 46 15 6e 0a 46
.L?!@.@. :#.F.n.F
0020 15 6e 85 ea 85 e6 46 fc c1 20 46 f8 a7 89 80 18
.n.?.?F? ? F??...
0030 7f ff e6 14 00 00 01 01 08 0a 00 14 01 18 00 14
.??..... ........
0040 01 00 47 49 4f 50 01 02 00 00 00 00 01 0c 00 00
..GIOP.. ........
0050 00 05 03 00 00 00 00 00 00 00 00 00 00 21 af ab
........ .....!??
0060 cb 00 00 00 00 20 60 5e ba b4 00 00 00 01 00 00
?.... `^ ??......
0070 00 00 00 00 00 00 00 00 00 04 00 00 00 00 0a 00
........ ........
0080 00 00 00 00 00 04 70 61 64 00 00 00 00 03 00 00
......pa d.......
0090 00 06 00 00 00 a0 00 00 00 00 00 00 00 28 49 44
..... .. .....(ID
00a0 4c 3a 6f 6d 67 2e 6f 72 67 2f 53 65 6e 64 69 6e
L:omg.or g/Sendin
00b0 67 43 6f 6e 74 65 78 74 2f 43 6f 64 65 42 61 73
gContext /CodeBas
00c0 65 3a 31 2e 30 00 00 00 00 01 00 00 00 00 00 00
e:1.0... ........
00d0 00 64 00 01 02 00 00 00 00 0d 31 30 2e 37 30 2e
.d...... ..10.70.
00e0 32 31 2e 31 31 30 00 00 85 eb 00 00 00 19 af ab
21.110.. .?....??
00f0 cb 00 00 00 00 02 60 5f 28 cd 00 00 00 08 00 00
?.....`_ (?......
0100 00 00 00 00 00 00 0a 00 00 00 00 00 00 01 00 00
........ ........
0110 00 01 00 00 00 20 00 00 00 00 00 01 00 01 00 00
..... .. ........
0120 00 02 05 01 00 01 00 01 00 20 00 01 01 09 00 00
........ . ......
0130 00 01 00 01 01 00 00 00 00 01 00 00 00 0c 00 00
........ ........
0140 00 00 00 01 00 01 00 01 01 09 4e 45 4f 00 00 00
........ ..NEO...
0150 00 02 00 0a 00 00 00 00 00 00
........ ..
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Padding.idl:
module Padding {
interface Pad {
void pad();
};
};
---
Client.java:
import org.omg.CORBA.ORB;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Properties;
public class Client
{
public static void main(String argv[])
{
try {
Properties props = new Properties();
// props.put("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
String[] args = new String[0];
ORB orb = ORB.init(args, props);
// read stringified object
//reference to a file
BufferedReader in = new BufferedReader(new FileReader(argv[0]));
String ior = in.readLine();
in.close();
org.omg.CORBA.Object obj = orb.string_to_object(ior);
Padding.Pad p = Padding.PadHelper.narrow(obj);
p.pad();
}
catch(Exception e) {
System.err.println("Unexpected exception: " + e);
e.printStackTrace();
}
}
}
---
Server.java:
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
public class Server
{
public static void main(String[] args)
{
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb =
org.omg.CORBA.ORB.init(args, null);
org.omg.CORBA.Object obj = orb.resolve_initial_references("RootPOA");
assert obj != null;
POA poa = POAHelper.narrow(obj);
assert poa != null;
// Create a stock object.
Padding.PadPOATie thePad =
new Padding.PadPOATie(new PadImpl());
// Let the ORB know about the object
poa.activate_object(thePad);
// Write stringified object
//reference to a file
PrintWriter out = new PrintWriter(new BufferedWriter(new
FileWriter(args[0])));
out.println(orb.object_to_string(thePad._this()));
out.close();
poa.the_POAManager().activate();
// wait for invocations from clients
orb.run();
}
catch (Exception e) {
System.err.println(
"Pad server error: " + e);
e.printStackTrace(System.out);
}
}
}
---
PadImpl.java:
public class PadImpl implements Padding.PadOperations
{
public void pad()
{
System.out.println("padit() called");
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
1. Using a different ORB for the client such as JacORB might
work, but the JacORB idl compiler does not work very well
making it difficult to compile some existing IDL.
// props.put("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
2. Use the same orb implementation at both ends. Difficult
if the server is not Java.
(Review ID: 164706)
======================================================================