Non-compliance Gallery
Home Mapping Info Non-compliance Gallery Java IDL FAQ Java IDL Library

 

The Gallery of  Java CORBA Non-Compliance

It is inevitable that given a specification, different readers will have different interpretations of how to translate that document into bits and bytes.

This page lists all the non-compliances I know about in Java implementations of OMG specifications.

Non-compliance can be difficult to prove. After all, no one has yet defined a foolproof mapping between English prose and binary digits. Therefore, even behavior that is not clearly non-compliant but merely at variance with other implementations of that behavior that is also not clearly non-compliant is worth discussing because it points to places where the specification may need to be clarified.

A major source of confusion is that CORBA vendors do not hesitate to claim compliance with OMG specifications but very rarely actually state with which specifications they actually comply. In the issues explored below, all documents relied upon directly are specified unambiguously.

Issue 1: CosNaming:NamingContext:rebind and OrbixWeb 3.0

COSNaming::NamingContext::rebind() wrongly fails with the CosNaming::NamingContext::NotFound exception when the Name does not exist in the context prior to invocation in Iona OrbixWeb 3.0 Update 1.

From the OMG CORBAservices Specification:

The CORBAservices Specification (OMG document formal/98-07-05) specifies the CosNaming::NamingContext::rebind method as follows, on page 3-8:
void rebind(in Name n, in Object obj)
   raises(NotFound, CannotProceed, InvalidName);

rebind

Creates a binding of a name and an object in the naming context even if the
name is already bound in the context. Naming contexts that are bound using
rebind do not participate in name resolution when compound names are
passed to be resolved.

Table 3-1 on page 3-9 specifies the exceptions that can be raised by any of the four binding operations (bind, rebind, bind_context, rebind_context) to be:

Table 3-1 Exceptions Raised by Binding Operations
 

Exception Raised Description
NotFound Indicates the name does not identify a binding.
CannotProceed Indicates that the implementation has given up for some reason. The 
client, however, may be able to continue the operation at the returned naming context.
InvalidName Indicates the name is invalid. (A name of length 0 is invalid; 
implementations may place other restrictions on names.)
AlreadyBound  Indicates an object is already bound to the specified name. Only one 
object can be bound to a particular name in a context. The bind and 
the bind_context operations raise the AlreadyBound exception if the name is bound in the context; the rebind and rebind_context operations unbind the name and rebind the name to the object passed as an argument.
 

From the OrbixWeb Documentation:

The OrbixWeb 3.0 Programmer's Guide, November 1997 (found in the OrbixWeb 3.0 for Win32 March 1998 distribution as Iona\OrbixWeb3.0\docs\OW3PrgGuide.pdf), page 184, documents the corresponding method org.omg.CosNaming.NamingContext.rebind as:
void rebind(in Name n, in Object o)
   raises ( NotFound, CannotProceed,
               InvalidName );

The rebind() operation creates a binding between a name that is already bound in the
context and an object. The previous name is unbound and the new binding is made in its
place. As is the case with bind(), all but the last component of a compound name must
name an existing NamingContext. A NotFound exception will be thrown if the name is
not already in use.

Analysis of the problem:

The OrbixWeb rebind method does indeed behave as documented: A NotFound exeception is thrown if the name is not already in use. Coupled with the statement that rebind "creates a binding between a name that is already bound in the context and an object", we deduce that this implementation will never create a binding where a binding involving that name does not already exist in the context.

However, the OMG Specification states that rebind will "[c]reate[] a binding of a name and an object in the naming context even if the
name is already bound in the context." The two key words here are even if. Those two words would not be necessary if creation were not intended to occur in other circumstances besides "already bound." The Iona description would be correct if the specification said only if but it does not.

To further bolster this interpretation, both Sun Java IDL (as of JDK 1.2 beta 4) and Inprise Visibroker for Java 3.2 both in text and in code make it clear that creation of a binding where none previously existed is the repsonsibility of the rebind method.

From Sun JDK 1.2 beta 4 documentation:

 rebind

public void rebind(NameComponent[] n,
                   Object obj)
            throws NotFound,
                   CannotProceed,
                   InvalidName

     Unbinds the given name from an object and rebinds it to the given object. If the given name is not already bound to an
     object, rebind simply binds the given name to the given object. If the given name is a compound name and any
     intermediate naming contexts are missing, this method throws the exception NotFound.

     Naming contexts that are bound using this method do not participate in name resolution when compound names are passed
     to be resolved.
     Parameters:
          n - Name of an object

     Throws:
          NotFound - if any intermediate nodes (naming contexts) are missing

          CannotProceed - when the implementation has given up for some reason. The client, however, may be able to
          continue the operation at the naming context returned by this exception.

          InvalidName - if the name is invalid

From the Visibroker Naming and Event Services 3.3 manual:

 void rebind(in Name n, in Object obj)
   raises(NotFound, CannotProceed, InvalidName);

     This method is exactly the same as the bind method, except that the AlreadyBound exception will never be raised. If the
     specified Name has already been bound to another object, that binding is replaced by the new binding.

Code that illustrates the problem:

Hello.idl:

#ifndef _HELLO_IDL
#define _HELLO_IDL

module Hello
{

  interface HelloWorld
  {
      void setHello(in string inString);
      void getHello(out string outString);

      attribute string color;

  };
};

#endif

HelloWorldServer.java:

package Hello;

import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;

public class HelloWorldServer extends _HelloWorldImplBase
{
  public static void main(String[] argv)
  {
    try
    {
     // create and initialize the ORB

     ORB orb = ORB.init(argv, null);

     // create servant and register it with the ORB
     HelloWorldServer server  = new HelloWorldServer();
     orb.connect(server);

     // get the root naming context
     org.omg.CORBA.Object obj =
     orb.resolve_initial_references("NameService");
     NamingContext ncRef = NamingContextHelper.narrow(obj);

     // bind the Object Reference in Naming
     NameComponent nc = new NameComponent("Hello", "");
     NameComponent path[] = {nc};
     ncRef.rebind(path, server);
     // Keep main from exiting.
     Wait.Wait();
    }
    catch (Exception e)
    {
      System.err.println("HelloWorldServer.main caught error " + e);
    }
 
  }

  public synchronized void setHello(String inString)
  {
      helloString = inString;
  }
 
  public synchronized void getHello(StringHolder outString)
  {
      outString.value = helloString;
  }

  public synchronized void color(String inString)
  {
      colorString = inString;
  }
 
  public synchronized String color()
  {
      return  colorString;
  }

  public HelloWorldServer() { }

  private String helloString = "Hello World";
  private String colorString = "Red";
 }

 class Wait {
  public static void Wait() {
    try {
      java.lang.Object sync = new java.lang.Object();
      synchronized (sync) {
      sync.wait();
      }
    } catch (Exception e) {
      System.err.println("Wait.Wait internal error " + e);
      System.exit(1);
   }
 }
}
// End of file.

BuildHelloOW.bat (for Windows):

rem Build HelloWorld for OrbixWeb 3.0

if not exist classes mkdir classes

idl     -jOMG -I. -jO . hello.idl

owjavac -classpath .;c:\iona\orbixweb3.0\classes;c:\jdk1.1.6\lib\classes.zip -d .\classes *.java

RunHelloOW.bat (for Windows):

@echo off
rem Running HelloServer with JDK 1.1.6 and OrbixWeb 3.0 Update 1 (on Windows 98):

rem 1. Unpack HelloJavaIDL source; make a note of where the JDK and Hello code resides and use below where appropriate in steps 2,3 & 7.
rem 2. Install JDK 1.1.6
rem 3. make sure JDK 1.1.6\bin is on %PATH%
rem 4. Install OrbixWeb 3.0
rem 5. Install Update 1 (or later) for OrbixWeb 3.0
rem 6. make sure OrbixWeb3.0\bin is on %PATH%
rem 7. cd %hello%
rem 8. buildhellow
 
echo This script pauses to let each service initialize. Hit a key after each service
echo displays some text.

echo Starting OrbixWeb Java daemon
start /m orbixdj
pause

echo Registering Iona's CosNaming Service
putit -j NS IE.Iona.OrbixWeb.CosNaming.NS

rem Modify classpath setting below to reflect location of JDK and OrbixWeb on your system
echo Starting HelloWorldServer
java -classpath .;.\classes;c:\iona\orbixweb3.0\classes;c:\jdk1.1.6\lib\classes.zip Hello.HelloWorldServer