Go to the previous, next section.

Using ILU with Java

Introduction

This document is for the Java programmer who wishes to use ILU. A programmer needs to know how ILU is mapped into Java constructs and how both Java clients and servers are generated and built. He also needs to stomach a fair load of search path, directory structure and command line lore.

We are still not done with the mapping. But neither is the OMG.

We expect a few more changes; sadly we also expect some of them to be visible to programmers. While we map most types the way we expect the omg to standardize, there is a major incompatibility still left: We don't yet handle nested modules the way of the omg... Also the PIDL needs some more work to look the standard way.

The ISL Mapping to Java

We will doubtless change the mapping to become closer to the OMG standard. See ftp://ftp.parc.xerox.com/pub/ilu/misc/Xerox-CORBA-to-Java-Mapping.html for our proposal. We do however already generate stubs which are closer to the expected OMG standard standard then to our proposal.

Using an ILU module from Java

The ILU runtime is in the java package xerox.ilu. The primary interface is the class Ilu.

A client program may access an ILU object in one of the following ways:

  1. Knowing the string binding handle sbh and class (or superclass) cl of an object, call xerox.ilu.Ilu.objectFromSBH(sbh, cl) which returns an instance of that class. For example, to obtain an instance of ISL type square from INTERFACE shapes whose string binding handle is sbh, one would call xerox.ilu.Ilu.objectFromSBH(sbh, shapes.square).
  2. Knowing the object ID (sid, ih) and class cl of an object that has been published using the simple binding service, call xerox.ilu.IluSimpleBinding.lookup(sid, ih, cl) which returns an instance of that class (or raises an excepotion if the lookup fails).
  3. Receive an instance as a result value from a method call that returns an object type or has an object type as an INOUT or OUT parameter.

Client side substitutions

It is possible to designate deeper subclasses to be used by ILU for certain types.

Record types could be subclassed and the Java class of the subclass assigned registered with the stub for the record. Whenever ILU needs to allocate an instance of such a record it will allocate a an instance of the subclass instead.

Implementing an ILU module in Java

A Java program(er) which wants to implement a object type T from interface I needs to create a class which implements the stubber-generated Java interface I. Objects of this class then are registered with the ILU runtime either implicitly or explicitly, or with an Object Table.

Explicit registration allows specification of additional parameters, like the string binding handle, the server used and more. Explicit registration done by calling the stubber generated method I.T_stub.registerTrueObject. As an alternative, if the programmer is willing to specify the class, he can also use the method xerox.ilu.Ilu.registerTrueObject directly.

Objects are implicitly registered with ILU if they are returned as a result value from a method call that returns an object type or has an object type as an INOUT or OUT parameter or if they are published using the Simple binding mechanism.

Hints about implicit registration

If objects are not registered but get auto-registered on use only there are two pitfalls to watch out for.

1) The ILU type must be unique. If no type is given ILU will look at the Java type and make its best possible guess about the ILU type.

2) The ILU type must be loaded. Unless the ILU type is loaded the guesser will never find that type. If there is any doubt about whether a stub implementing an ILU type is loaded or not, it might be useful to actually load the class. The xerox.basics.Environment class can be used to load a class from external commands. The stubber also generates a special class whose sole purpose is to help loading whatever is necessary for the guesser to not miss a class.

True Servers

Each object exported by an implementation must belong to a true server, an instance of the Java type IluServer which is implemented by the xerox.ilu.IluServer class.

An IluServer can be created by calling the function ilu.createServer([serverID]), which returns a value of type IluServer. If serverID is a string, it specifies the server ID; if it is None, one will be invented automatically.

Other methods allow the specification of a daemon flags or ports for different transports or protocols, or an object table.

An objectTable allows specification of a callback function for creating true instances on demand.

The first time a true server is created, it becomes the default server. The default server is used for an exported object if a server is not otherwise specified or when it is explicitly requested with the defaultServer method. If an object is exported before any servers have been created, one will be created automatically using default parameters and possibly a message to that effect will be written to System.err.

An object of type IluServer has an accessor method serverId() that returns its server ID.

Directories, Packages, and Modules

The first time you see any of these tree structures you are bound to be overwhelmed. However, it is not that bad if you know some of the reasoning. If you have a good understanding of the java system building concepts without ILU, this might be easy to follow.

Java without ILU

The Java compiler takes Java sources and creates binaries, typically called class files. (Never mind, that the word "class" has as a meaning in the source domain as well). The java compiler conceptionally copes with 4 file hierarchies.

Sad to say, Sun's documentation is not conceptionally clean. The functionality is different when directories are specified as command line options or with environment variables.

1) Java sources can be thought of as tree structured in the package domain. You may or may not assume that sources are stored in a similar directory nesting as the package nesting. This is not an important issue because the Java compiler lets users specify source files explicitly. (Unless you are working with very explicitly make files, I recommend compiling multiple sources with one single compile command and let the java compiler worry about dependencies)

2) Precompiled binaries can be found using the classpath command line switch or the CLASSPATH environment variable. The semantics is different! The classpath command line switch must be complete (including system binaries). If the CLASSPATH environment variable is used the standard binaries are automatically accessed. You can work either way, if you know the difference.

3) The most important monkey wrench to know about is #3; where are compiled binaries stored. The -d option allows to specify a directory. Absence of the -d option takes the working directory. HOWEVER: With the -d option binaries are stored hierarchically in the destination directory, according to their package structure. Without the -d option binaries are stored directly in the curent working directory. RECOMMENDATION: Always use the -d option. If the -d option is not used some Java tools will not find the binaries... Don't get confused that "Hello World" programs can be compiled without -d option; real programs can't.

4) The compiler itself loads binaries from the CLASSPATH environment variable. Be warned, that is the same environment variable as used in 2)

To make matters worse

Summary

We recommend a compiler usage by which the input, independent of its structured is compiled into a hierarchical file structure hanging on a directory called "./classes". We also recommend putting the "./classes" directory into the CLASSPATH so that the Java loader finds the compiled binaries.

ILU enters the picture

Stubbing

Java Compilation

Unless you are using make files we recommend stubbing into empty directories. This allows to use the java compiler do compile all java files with an asterisk syntax. Use the -d option!!!

Execution

At execution time the loader needs to find

1) Is normal... use the CLASSPATH environment variable.

2) There is nothing special here. Compile the stubs into whatever directory you want (e.g.) "./classes" and put that directory on the CLASSPATH environment variable.

3) The classes binaries from the ILU runtime support are compiled into a directory $(ILUHOME)/lib/javaclasses. The reason for this non-standard place is the fact that some ILU developers believe the subdirectory ./classes should be reserved for some other purpose.

4) The C binaries (object files) are accessed using the LD_LIBRARY_PATH. The path must have an entry pointing into the ILU java runtime directory.

Debugging

The standard ILU debugging environment variable ILU_DEBUG is recommended.

Java Ilu listens to a large number of java command line switches to your application. The simplest one is to set the -D command line option -Dilu.debug.default=4 . For more specialized command line switches look at the xerox.ilu.IluDebug.java file.

Note that the -D option of the java interpreter has no relationship whatsoever to the -d option of the java compiler.

Hint when using dbx or gdb The standard java binaries (classes) are found automaticly (without specification on the CLASSPATH environment variable) when not debugging. When debugging, those classes MUST be specified on the CLASSPATH... Don't ask me why the difference.

Packages

What package to use ? Java-ILU is deeply committed to give the choice to the application. (That is why the prefix package is optional).

An application programmer will face the decision whether the implementation for true object should be in the package designated for stubs, or in a package of its own. Both choices do make sense; ILU will work either way and doesn't make that decision for you. In general we expect most applications to prefer working in one single package. However we can imagine scenarios where for security reasons a stub could be trusted but a server object might not be trusted, or they'd be signed independently by different entities.

But PLEASE: Don't ever write java code which is not in a package at all. You will end up putting it in a package later anyway. It will be much more work later then at the beginning to set up all your commands and files to work with a package.

Versions, releases, and, machines

Java ILU works on any machine, operating system, Java version of your choice, as long as your choice is a Sparcstation running Solaris 2.x and Java JDK 1.0.2 or JDK 1.1.1. This will of course improve.

Stub Generation

To generate Java stubs from an ISL file, use the program java-stubber. The stubber reacts to some command line options. All command line options (except if documented specifically) have a second variant with a suffix "1". If the command line option with suffix is used, an extra argument for the name of an interface is read. The suffixed command line options are valid for the particular named interface; the un-suffixed command line options are valid for all interfaces. (Suffixed command line options override un-suffixed command line options. Option processing is from left to right.) Since the stubber creates a surprisingly large number of java files, these files must be directed to a designated stub directory. For the same reason a file with a list of generated java files is generated.

Using the Simple Binding Service

An object may be published using the simple binding service by calling the method xerox.ilu.IluSimpleBinding.publish().

An object may be unpublished by calling the method xerox.ilu.IluSimpleBinding.withdraw().

A published ILU object may be obtained by calling xerox.ilu.IluSimpleBinding.lookup(sid, ih, cl), where sid is object's server's server ID, ih is the object's instance handle, and cl is its class.

Go to the previous, next section.