[Up: Object Adapters]
[Previous: Object Adapters] [Next: Portable Object Adapter]
The Basic Object Adapter was introduced with the first version of CORBA in 1991 and has been largely unchanged since then. Its purpose was to be a simple and generic type of object adapter that could be used, as the name suggests, for basic purposes. As such, its interface is intentionally minimalistic, providing a total of 10 methods, conveniently specified in IDL as shown in figure 4.2.
The Basic Object Adapter defines three states that an object can enter during its lifetime: not existent, inactive, and active. Not surprisingly, an object is initially in the ``not existent'' state, meaning that the ORB does not know of the object and that invocations are not possible but rejected with an appropriate error message.
The ``creation'' calls an object into being. From that point on, object references can be exported. Clients can receive object references for inactive objects, but method invocations will be withheld on the server side by the BOA and block until the object transitions to the active state. After activation, method invocations received by the ORB core are passed on to the implementation until it is deactivated again.
The process of object activation and deactivation can happen more than once and is transparent to the client. A server might wish to disallow upcalls from the ORB for some time while other tasks are done, or to replace the implementation.
Once an object is not needed anymore, it can be destroyed to return to the not existent state, causing the BOA to act as if it had never existed. Destruction is final; although the BOA's interface would allow for the reincarnation of an object - the creation of a new object that answers to the same object references as before, this is forbidden by the specification, which said that two creations, even with the same parameters, will never produce the same object.
Another central concept introduced by the Basic Object Adapter is the ``Implementation Repository.'' Corresponding to the Interface Repository as a database for the abstract declaration of an object's interface, the Implementation Repository was to be a database of program code for an object's implementation. As seen before, an IOR contains both a type and an address to an implementation. The BOA employs this idea; object creation is done by associating an interface with an implementation using the create method.
The BOA is aware of processes and servers, and is designed to start up new servers by itself if necessary. One information kept in the Implementation Repository is the activation policy, so termed because it determines when a new server must be activated in order to serve a request.
The actual contents of the Implementation Repository are not specified by the CORBA standard but must be defined by the ORB implementation. As per the text above, an entry must contain at least the activation policy and information about a server process (e.g. a path name to an executable program).
From the specification, some implementation details can be deduced. Seen from a process-oriented perspective, the BOA must be realized in two parts. One part must be included in each server to receive requests and to perform upcalls into the object implementations. The other part has to keep track of all implementations in the Implementation Repository and to start new servers if necessary. This second part could be realized either as a permanently running daemon or be integrated in each client.
It is interesting that some over-enthusiastic literature [44] cannot find fault with the BOA and coin it a ``fairly flexible adapter'' [63]. But problems become obvious when actual servers are to be written according to the specification. As seen in figure 4.2, the create operation is used to call an object into existence by associating an interface with an implementation. An Implementation Repository holds information about the server program, but no user code. Once the BOA has started a new process in order to activate an object, the BOA needs to perform upcalls into user code to perform invocations - but the BOA does not provide a means of registering servants. Information about servants cannot be kept in the Implementation Repository itself, for they only exist in a live server (for example, C++ objects). Already in this very important respect, each ORB vendor must use proprietary additions to the standard in order to get the BOA to work.
This error is not mended with the simple addition of one or more methods. Rather, the standard did not even provide a basic structure for server-side programming. While it requires the IDL compiler to generate skeletons from which an object implementation is to be derived, their inheritance, behavior and even name are undefined.
More problems arise when considering an object's lifetime, which can exceed the lifetime of the server it was created in. Objects may need persistent storage for their internal state while a server is not running. When a server is started by the BOA, the program cannot determine which objects are to be restored. Only within a method, during execution of a request, can a program determine the object reference which is the target of the request4.1 - at which point it is too late, or rather very inconvenient, to restore state data.
If an implementation tries to take saving and restoration of objects into its own hands, it is likely to run into a race condition. There's no point in time at which the data could be written, because the transition from the active to the inactive state is instantaneous to the BOA. Before deactivation, requests are still delivered and state data may change. After calling deactivate_impl, the BOA may immediately start up a new server before the old server has finished writing its data.
Once the problems of registration and state restoration are taken care of, a server runs into another omission. After initialization, a server needs to wait for incoming requests, but the specification does not define how this is done. Some BOA implementations make impl_is_ready and obj_is_ready block and wait for requests until deactivate_impl or deactivate_obj is called. While this decision is sensible, the process of waiting for incoming requests it is not referred to in the documentation.
In summary, the problems with the BOA are numerous and can be put into three categories.
Many vendors have chosen to make usage of the BOA as transparent as possible: registration is performed in a servant's constructor, and creation of object references is made transparent by skeletons inheriting their own object reference. Some vendors have chosen to abandon the Implementation Repository completely and only provide the persistent activation policy, like ORBacus [41].
This way, the existence of the BOA is mostly hidden from the developer, and calls into the BOA like impl_is_ready are left over as part of initialization ``magic,'' unrelated to the original intention of object adapter programming.
The Basic Object Adapter has failed twice. It was never designed to be a general-purpose object adapter, but only intended as a first option. The OMG expected more specialized object adapters to appear over time. Their reasoning was that no all-powerful object adapter was achievable, as each brings its own design limits, so that object adapters would have to be tailored to specific purposes.
But even in this respect, the BOA did not fulfill its expectations because of its severe design flaws.
The combination of both points did have the unfortunate side effect that since ORB vendors did have to tamper with the BOA specification to make it work in the first place, they did not finish with incompatible but still recognizable Basic Object Adapters, but extended their BOA adaptation with new features as well, like synchronization, threading primitives, or an interface for storage and restoration of persistent data.
In this the vendors left the intended path of the OMG. The most effective way of dealing with an insufficient BOA would have been to introduce an object adapter of their own design. Rather, CORBA was now stuck with many incompatible object adapters that still called themselves ``BOA,'' but that did come, apart from the necessary fixes, with individual custom features.
The Object Management Group recognized the impossibility to write portable server code, and as a result issued the ``ORB Portability Enhancement RFP'' [25] in June 1995, in parallel to the publication of the second version of the CORBA standard. It called for ideas on how to improve the situation, naming four possible solutions:
The final reasoning of the OMG was that the problems with the BOA were too numerous to be fixed with minor adjustment, and that any changes would break existing server code that based on proprietary BOA extensions.
By applying the ``sunset policy'' and removing the BOA specification entirely, the BOA did after all become a vendor-specific extension, allowing existing server programs to live on unchanged, but with the definite tag of being unportable.
The newly introduced Portable Object Adapter was set in its place as the new ``one size fits all'' general-purpose object adapter. However, when the ORB Portability Joint Submission was released, it once again violated the OMG's policy of adopting only existing technology. While the original RFP stated that ``submitters are expected to have working implementations of their proposed specifications'' at the time of initial submission, the final submission still mentions that only ``some prototyping and detailed design work'' had been done, and offers the vague hope that ``products based on this design will be available within the OMG's timelines.''
When the CORBA 2.2 specification was released, this had not happened.
[Previous: Object Adapters] [Next: Portable Object Adapter]
[Up: Object Adapters]