Back to the overview Bojangles Tools User's Guide and Status *

Java Application Web Server
User's Guide to Tools and Tool Status

  • Overview
  • Data Flow for Emitter Tools
  • User's Guides
  • RunInterfaceEmitter and RunImplEmitter
  • Base File Cookbook
  • Running the Base Emitters
  • RunStubEmitter
  • RunSkeletonEmitter
  • RunFlexMOEmitter
  • RunSRootMOEmitter
  • The FilePOBC Emitter
  • Tools for Service Providers
  • Overview

    A number of tools are provided that generate the special interface or class files that are required by the Bojangles environment from hand written files provided by a programmer.

    Bojangles requires a number of class and interface definitions for each business object. The tools described below can generate most of these files so that the actual burden on the programmer is very small. In order to reduce complexity a set of naming conventions are followed for these files. Briefly the files and their naming convention are (assuming that the base name of the business object is XXX and it is to be managed by the YY base collection):

    Base file (named XXXBase.java)
    A hand written file that provides the essential implementation of the business object. This file is not exposed to the client of the object.
    Interface file (named XXX.java)
    This file can be generated is some cases, but should usually be hand written. It defines the external interface of the business object.
    Implementation file (named XXXImpl.java)
    This file represents the actual implementation of the business object to client of the object. It differs from the base file in that certain parts of the implemenation required by Bojangles are added. In particular these include the externalizeToStream and internalizeFromStream methods. (Some restrictions apply on the generation of this file as discussed below.) Some of the tools discussed below depend on this file. This file can be generated or hand written and, either way, those tools will work just fine.
    Stub file (named XXXStub.java)
    Remote objects are represented by stub (sometimes called proxy) objects on the client. This file provides the implementation of the stub objects for the business object.
    Skeleton file (named XXXSkeleton.java)
    Skeletons are used by the ORB to assist in invoking methods on a server object. This file privides the implementation of the the skeleton objects for the business object.
    Managed file (named XXXYYMO.java)
    In order for a base collection to hold a particular business object it is necessary to generate a subclass of the business object that is specific to the base collecton. This subclass will implement the Managed interface and any special methods required by the base collection. A managed file must be generated for each type of base collection that the business object can be contained in. Also, most base collections require a second subclass of the business object which is usually not exposed to clients of the base collection. Where necessary a generator for this file is also supplied.

    The following tools are provided. Note: all tools take as input the compiled version of the file not the source version. Thus to run the tool you must be able to compile its input file. This is the main reason for hand writting the interface files.

    RunInterfaceEmitter
    This is a Java program that takes base implementation class for an application object and generates a Java interface file for it with get/set methods for each of the attributes and declarations for its public methods. Note: you must have compiled the base class first which frequently depends on the external interface files which you are trying to generate. For this reason, you may have to stub out the interface file or you may find that you have to hand write the interface file. A reasonable approach is to stub out the interface file early in you development, use this tool to generate an interface file and then hand maintain the interface file. (This tool is still in development and has some limitations, be sure to read over the generated file to be sure it is what you want.)
    RunImplEmitter
    This is a Java program that takes the same input as RunInterfaceEmitter and produces a Java class that implements the interface produced by RunInterfaceEmitter. (This tool is still in development and has some limitations, be sure to read over the generated file to be sure it is what you want.)
    RunStubEmitter
    This is a Java program that takes the Java compiled class file for a application object's interface and produces a IIOP stub class for it.
    RunSkeletonEmitter
    This is a Java program that takes the Java compiled class file for a application object's interface and produces a IIOP skeleton class for it.
    RunFlexMOEmitter
    This is a Java program that takes the compiled class file of an application object's implementation class and produces a Managed object for the object that will work with the FlexBC BaseCollection.
    RunSRootMOEmitter
    This is a Java program that takes the compiled class file of an application object's implementation class and produces a Managed object for the object that will work with the SimpleRootBC BaseCollection.
    FilePOBC
    RunManagedDelEmitter
    This is a Java program that takes the compiled class file of an application object's implementation class and produces a Managed object for the object that will work with the FilePOBC BaseCollection.
    RunCachedEmitter
    This is a Java program that takes the compiled class file of an application object's implementation class and produces a special subclass of the object that is required internalling in the FilePOBC BaseCollection.
    Documentation for the emitter tools that support the FilePOBC are found in the overview for it.

    Data flow for emitter tools

    Assume that XXX is the name of the application object's interface and that YY is the name of the base collection that the object will be used with. Only the XXXBase file is produced by hand, all the other files are completely generated. (You may also choose to hand-write the XXX file.)

    
      XXXBase--+------------>XXX--+-------------->XXXStub
               |                  |
               |                  |
    	   |		      +-------------->XXXSkeleton
    	   |
    	   +------------>XXXImpl------------->XXXYYMO
    
    

    In the above, Java source files are produced and compiled java files (class files) are used to produce the next step. For example, XXXBase.java is compiled to produce XXXBase.class which is then used to generate XXX.java, which is then compiled to produce XXX.class which is used produce XXXStub.

    For some CORBA and BaseCollection features more information is needed to drive the emitting process than can be extracted from the Java class files as they are produced by the compiler. For example, CORBA supports one-way methods, but there is no way to indicate this in Java source. However, Java class files have an architected extension mechanism that allows additional information to be added to the class file that will not effect its use by interpreters. Therefore, we have developed a utility that takes a file (XXXBase.attributes) with attribute name/value pairs in it and adds the information to the class file. Currently we do not support any features that require this extra information, but we will soon. When we begin to use attribute files the data flow will become:

    
            XXXBase.attributes  XXXBase.java
                     |               |
                     +-------+-------+
    		         |
    			 v
                       XXXBase.class
                             |
            +------------+---+-----------+------------------+
    	|            |               |                  |
    	v	     v		     v			v
     XXX.attributes  XXX.java     XXXImpl.attributes   XXXImpl.java
    	|            |               |                  |
    	+------+-----+               +----------+-------+
    	       |                                |
    	       v				v
               XXX.class                      XXXImpl.class
    	       |                                |
           +-------+-------+                        |
           |               |			|
           v	       v			v
     XXXStub.java    XXXSkeleton.java           XXXYYMO.java
    

    Only the XXXBase.attributes and XXXBase.java files need to be handwritten. Although, it is frequently best to also handwrite the XXX file.

    User's Guides

    RunInterfaceEmitter and RunImplEmitter

    These two programs (called the base emitters) are convenience tools provided to help in generating and maintaining application objects. They can save a lot of effort during the development of an application object.

    Basicially, these tools allow you to maintain one simple Java source file and generate the Java interface and implementation files required for the Bojangles environment. You don't have to use these tools, it is quite reasonable to produce your interface and implementation files manually.

    The concept behind these tools is to maintain one class file that contains a field definition for each of your attributes and provides an implementation for each of the methods you need to implement your object's interface. If you are developing an application object whose interface is to be called XXX, then the file that you hand write should be called XXXBase.java. From this file, RunInterfaceEmitter will generate an interface file, XXX.java. RunImplEmitter will generate an implementation class file, XXXImpl.java, that "implements" XXX and "extends" XXXBase. Whenever you change XXXBase.java in a way that affects its interface you must regenerate both XXX.java and XXXImpl.java.

    Base File Cookbook

    The XXX.java file will extend COM.ibm.jaws.mofw.Manageable. The XXXImpl.java file will provide implementations for any of the methods required by Manageable that you don't provide in your base file. In addition the base emitters will provide interfaces and implementations for each of your object's "attributes".

    Follow these steps in your base file implementation

    1. Attributes

      Usually, application objects have a number of get/set method pairs that are referred to as attributes. Usually each get method returns the value of a field in the object and each set method sets the value of the same field.

      For each read/write attribute you want to have, define a field in your base file with the "protected" access attribute. For example:

             protected int x;
             protected String y;
          
      Each such field will result in a get/set method pair being defined in the generated interface file and corresponding method implementations in the generated implementation file. For example:
             public interface XXX {
      
      	  // ...
      	  public int x();
      	  public void x(int value);
      	  public String y();
      	  public void y(String value);
      	  // ...
             }
      
          and
      
             public class XXXImpl extends XXXBase implements XXX {
      
      	  // ...
      	  public int x() { return x; }
      	  public void x(int value) { x = value; }
      	  public String y() { return y; }
      	  public void y(String value) { y = value; }
      	  // ...
             }
          

      If you define a field that is final, then only a get method will be generated for it.

      If you have a more complicated requirement for some of your attributes then declare their associated fields as private and define your own get/set methods.

      Make all fields that you don't want to become attributes "private".

      Access fields in your object directly not by their get/set methods. (This is more efficient.)

      Issue: The Impl emitter cannot generate externalizeToStream and internalizeFromStream support for private fields, therefore all persistent fields need to be protected (or public). This will result in the generation of get/set methods for these fields. It should be possible to indicate that a protected field is NOT an attribute and prevent the generation of get/set methods. This will be added in the next release of these tools. In the meantime you can use the emitters to generate externalizeToStream and internalizeFromStream methods and then copy the methods back to your base file and edit their content. You will have to maintain these two methods after this as their presence in your base file will prevent their generation into the impl file.

      Issue: Bojangles does not support direct externalization of Java objects that do not support the interface COM.ibm.jaws.mofw.Manageable, except for java.lang.String. Therefore you cannot have attributes (fields with get/set methods) or persistent fields that are other types of Java object (such as arrays, Vectors, URLs, etc.). If the objects you want to use are subclassable then you can subclass them an make them Manageable (write internalize/externalize methods for them). If they are not subclassable or you don't want to make them manageable then you cannot make them attributes and if you want to make them persistent will will have to write your own internalize/externalize methods as described above. When Java serialization support becomes widely deployed we will remove this restriction.

    2. Methods:

      For each method that you want to be in your object's interface define a method in your base file with the "public" access attribute. For example:

             public int computeValue() { /* ... */ }
          
      This will produce a declaration in the generated interface file. It will not produce anything in the generated implementation file.

      Make all methods that you don't want in your interface either private or protected. (Static methods will also not become a part of your interface.)

    3. Externalize/Internalize

      The base implementation emitter will generate externalizeToStream and internalizeFromStream methods for you based on your object's fields. Each "public" or "protected", non-"transient", non-"static", field will be written out and read in.

      To enhance the value of generated externalizeToStream and internalizeFromStream methods an interface, COM.ibm.jaws.motk.Activation, is provided. The generated externalizeToStream will call the prepareForExternalization method from this interface before begining externalization. This allows you to update any of your persistent fields from transient data if necessary. The generated internalizeFromStream will call activate from this interface after internalization is complete. This allows you to update any transient state after internalization. You may also find it convient to use activate after object construction. For example, you might new-up an instance of one of your objects. Call a series of set methods to initialize its state and then call activate to finish its initialization. You might also call activate from any constructors that fully initialize the object.

      If this is not correct or you need to do more then you must define these methods yourself. You can use the emitters to generate externalizeToStream and internalizeFromStream methods and then copy the methods back to your base file and edit their content. You will have to maintain these two methods after this as their presence in your base file will prevent their generation into the impl file.

    4. release, remove, setDependentContext, setSelf

      If you don't provide implementations of these methods then the base implementation emitter will generate default implementations of them that do nothing.

    Running the Base Emitters

    The base emitters are run from a command line with the compiled version of your base file as input. The syntax of the commands are:

    
        java COM.ibm.jaws.tools.emit.RunInterfaceEmitter
           baseClass [ targetPackage ]
    
        java COM.ibm.jaws.tools.emit.RunImplEmitter
           baseClass [ targetPackage ]
    
    

    Where:

    baseClass
    is the fully qualified Java class name for your base class, which must already be compiled.
    targetPackage
    is the name of the package that the emitted file will be in. This parameter is optional. It defaults to the same package as the base class.

    For example:

        java COM.ibm.jaws.tools.emit.RunInterfaceEmitter
           COM.ibm.jaws.models.trs.UserBase COM.ibm.jaws.models.trs
      
        java COM.ibm.jaws.tools.emit.RunImplEmitter 
           COM.ibm.jaws.models.trs.UserBase COM.ibm.jaws.models.trs
    
    Each of these commands will produce files in the directory in which the program is run with appropriate names (e.g., User.java and UserImpl.java).

    RunStubEmitter

    To run RunStubEmitter to generate a stub file from an interface file, type the following command.
         java COM.ibm.jaws.tools.emit.RunStubEmitter
            interface [ targetPackage ]
    

    Where:

    interface
    is the fully qualified class name of your interface, e.g., COM.ibm.jaws.models.trs.User.
    targetPackage
    is the name of the package that the emitted file will be in. This parameter is optional. It defaults to the same package as the base class.

    Note:A restriction in the current Bojangles distribution support requires that you generate stub and skeletons with the same package as their interface class. This restriction will be removed shortly.

    RunSkeletonEmitter

    To run RunSkeletonEmitter to generate a skeleton file from an interface file, type the following command.
         java COM.ibm.jaws.tools.emit.RunSkeletonEmitter
            interface [ targetPackage ]
    

    Where:

    interface
    is the fully qualified class name of your interface, e.g., COM.ibm.jaws.models.trs.User.
    targetPackage
    is the name of the package that the emitted file will be in. This parameter is optional. It defaults to the same package as the base class.

    Note:A restriction in the current Bojangles distribution support requires that you generate stub and skeletons with the same package as their interface class. This restriction will be removed shortly.

    RunFlexMOEmitter

    To run RunFlexMOEmitter to generate a managed object file from an impl file, type the following command. Your impl file must support the interface COM.ibm.jaws.mofw.Managable. This emitter will add the methods and fields required by the FlexBC base collection for objects it will manage. If you object is a key-in-data type of object then your impl file must also support a method, getKey, which returns your object's key. Future versions of FlexBC will allow other ways to specify how to derive a key from the object's data. If you will be suppling the key in the create calls for you object then you don't have to implement getKey.

    In addition to producing an Managed object for FlexBC to use, you need to register this in the context.cfg file for your application. (See the documentation for SimpleRootBC for how to do this.)

         java COM.ibm.jaws.tools.emit.RunFlexMOEmitter
            impl [ targetPackage ]
    

    Where:

    impl
    is the fully qualified class name of your impl file, e.g., COM.ibm.jaws.models.trs.UserImpl.
    targetPackage
    is the name of the package that the emitted file will be in. This parameter is optional. It defaults to the same package as the base class.

    RunSRootMOEmitter

    To run RunSRootMOEmitter to generate a managed object file from an impl file, type the following command. Your impl file must support the interface COM.ibm.jaws.mofw.Managable. This emitter will add the methods and fields required by the SRootBC base collection for objects it will manage.

    In addition to producing an Managed object for SimpleRootBC to use, you need to register this in the context.cfg file for your application. (See the documentation for SimpleRootBC for how to do this.)

         java COM.ibm.jaws.tools.emit.RunSRootMOEmitter
            impl [ targetPackage ]
    

    Where:

    impl
    is the fully qualified class name of your impl file, e.g., COM.ibm.jaws.models.trs.UserImpl.
    targetPackage
    is the name of the package that the emitted file will be in. This parameter is optional. It defaults to the same package as the base class.

    Tools for Service Providers

    The SOM Emitter Framework is documented in a separate document. This is a Java package for developing emitter tools such as the ones described above in this document.