BEA Logo BEA WebLogic Enterprise Release 5.0

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   WLE Doc Home   |   CORBA Programming & Related Topics   |   Previous   |   Next   |   Contents   |   Index

Java TP Framework

This container covers the following topics:

The WLE Java TP Framework provides a programming framework that enables users to create servers for high-performance TP applications. The Java TP Framework is required when developing WLE servers. This chapter describes the architecture of and interfaces in the Java TP Framework. Information about the Java TP Framework API is in the Java API Reference. Information about how to use this API can be found in Creating Java Server Applications.

WLE uses BEA TUXEDO as the underlying infrastructure for providing load balancing, transactional capabilities, and administrative infrastructure. The base API used by the TP Framework is the CORBA API with BEA extensions.

Before WLE, ORB products did not approach BEA TUXEDO's performance in large-scale environments. BEA TUXEDO systems support applications that can process hundreds of transactions per second. These applications are built using the BEA TUXEDO stateless-service programming model that minimizes the amount of system resources used for each request, and thus maximizes throughput and price performance.

Now, WLE and its Java TP Framework let you develop CORBA applications with performance similar to BEA TUXEDO applications. WLE servers that use the Java TP Framework provide throughput, response time, and price performance approaching the BEA TUXEDO stateless-service programming model, while using the CORBA programming model.

The Java TP Framework consists of:

A Simple Programming Model

The Java TP Framework provides a simple, useful subset of the wide range of possible CORBA object implementation choices. You use it for the development of server-side object implementations only.

When using any client-side CORBA ORB, clients interact with CORBA objects whose server-side implementations are managed by the Java TP Framework. Clients are unaware of the existence of the TP Framework-a client written to access a CORBA object executing in a non-BEA WLE server environment will be able to access that same CORBA object executing in a WLE server environment without any changes or restrictions to the client interface.

The Java TP Framework provides a server environment and an API that is easier to use and understand than the CORBA Portable Object Adapter (POA) API, and is specifically geared towards enterprise applications. It is a simple server programming model and an orthodox implementation of the CORBA model, which will be familiar to programmers using ORBs such as ORBIX or VisiBroker.

The Java TP Framework simplifies the programming of WLE servers by reducing the complexity of the server environment in the following ways:

The Java TP Framework provides the following functionality:

The TP Framework API is available for use in either a single threaded or multi-threaded Java server.

Control Flow

The Java TP Framework, in conjunction with the ORB and the POA, controls the flow of the application program by doing the following:

Object State Management

The Java TP Framework API provides callback methods for application code to implement flexible state management schemes for CORBA objects. State management involves the saving and restoring of object state on object deactivation and activation. State management also concerns the duration of activation of objects, which influences the performance of servers and their resource usage. The default duration of object activation is controlled by policies assigned to implementations at IDL compile time. For more information about object state management, see the section "Object State Management" on page 3-6.

Transaction Integration

Java TP Framework transaction integration provides the following features:

Object Housekeeping

When a server is shut down, the Java TP Framework rolls back any transactions that the server is involved in and deactivates any CORBA objects that are currently active.

High-level Services

The TP interface in the Java TP Framework API provides methods for performing object registrations and utility functions. The following services are provided:

The purpose of this interface is to provide high-level calls that application code can call, instead of calls to underlying APIs provided by the Portable Object Adapter (POA) and the BEA TUXEDO system. By encapsulating the underlying API calls with a high-level set of methods, programmers can focus their efforts on providing business logic, rather than on understanding and using the more complex underlying facilities.

Object State Management

Object state management involves the saving and restoring of object state on object deactivation and activation. It also concerns the duration of activation of objects, which influences the performance of servers and their resource usage. The external API of the Java TP Framework provides activate_object and deactivate_object methods, which are a possible location for state management code.

Activation Policy

State management is provided in the TP Framework by the activation policy. This policy controls the activation and deactivation of servants for a particular IDL interface (as opposed to the creation and destruction of the servants). This policy is applicable only to CORBA objects using the Java TP Framework.

The activation policy determines the default in-memory activation duration for a CORBA object. A CORBA object is active in a POA if the POA's active object map contains an entry that associates an object ID with an existing servant. Object deactivation removes the association of an object ID with its active servant. You can choose from one of three activation policies: method (the default), transaction , or process .

Note: The activation policies are set in an Server Description file that is configured at OMG IDL compile time. For a description of the Server Description file, refer to Chapter 2, Server Description File.

The activation policies are described below:

Application-controlled Activation and Deactivation

Ordinarily, activation and deactivation decisions are made by the Java TP Framework, as discussed earlier in this chapter. The techniques in this section show how to use alternate mechanisms. The application can control the timing of activation and deactivation explicitly for objects with particular policies.

Explicit Activation

Application code can bypass the on-demand activation feature of the Java TP Framework for objects that use the process activation policy. The application can "preactivate" an object (that is, activate it before any invocation) using the com.beasys.TP.create_active_object_reference call.

Preactivation works as follows. Before the application creates an object reference, the application instantiates a servant and initializes that servant's state. The application uses com.beasys.TP.create_active_object_reference to put the object into the Active Object Map (that is, associate the servant with an ObjectId ). Then, when the first invocation is made, the Java TP Framework immediately directs the request to the process that created the object reference and then to the existing servant, bypassing the call to the servant's activate_object method (just as if this were the second or later invocation on the object). Note that the object reference for such an object will not be directed to another server and the object will never go through on-demand activation as long as the object remains activated.

Since the preactivated object has the process activation policy, it will remain active until one of two events occurs: 1) the ending of the process or 2) a com.beasys.TP.deactivateEnable call.

Usage Notes

Preactivation is especially useful if the application needs to establish the servant with an initial state in the same process, perhaps using shared memory to initialize state. Waiting to initialize state until a later time and in a potentially different process may be very difficult if that state includes pointers, object references, or complex data structures. com.beasys.TP.create_active_object_reference guarantees that the preactivated object is in the same process as the code that is doing the preactivation. While this is convenient, preactivation should be used sparingly, as should all process objects, because it preallocates precious resources. However, when needed and used properly, preallocation is more efficient than alternatives.

Examples of such usage might be an object using the "iterator" pattern. For example, there might a potentially long list of items that could be returned (in an unbound IDL sequence) from a "database_query" method (for example, the contents of the telephone book). Returning all such items in the sequence is impractical because the message size and the memory requirements would be too large.

On an initial call to get the list, an object using the iterator pattern returns only a limited number of items in the sequence and also returns a reference to an "iterator" object that can be invoked to receive further elements. This iterator object is initialized by the initial object; that is, the initial object creates a servant and sets its state to keep track of where in the long list of items the iteration currently stands (the pointer to the database, the query parameters, the cursor, and so forth).

The initial object uses com.beasys.TP.create_active_object_reference to preactivate this iterator object and to create its reference which will be returned to the client. It also creates an object reference to that object to return to the client. The client then invokes repeatedly on the iterator object to receive, say, the next 100 items in the list each time. The advantage of preactivation in this situation is that the state might be complex. It is often easiest to set such state initially, from a method that has all the information in its context (call frame), when the initial object still has control.

When the client is finished with the iterator object, it invokes a final method on the initial object, which deacativates the iterator object. The initial object deactivates the iterator object by invoking a method on the iterator object that calls the com.beasys.TP.deactivateEnable method; that is, the iterator object calls com.beasys.TP.deactivateEnable on itself.

Caution

For objects to be preactivated in this fashion, the state usually cannot be recovered if a crash occurs. (This is because the state was considered too complex or inconvenient to set upon initial, delayed activation.) This is a valid object technique, essentially stating that the object is valid only for a single activation period.

However, a problem may arise because of the "one-time" usage. Since a client still holds an object reference that leads to the process containing that state, and since the state cannot be recreated after the crash, care must be taken that the client's next invocation does not automatically provoke a new activation of the object, because that object would have inapplicable state.

The solution is to refuse to allow the object to be activated automatically by the TP Framework. If the activate_object method throws a com.beasys.TobjS.ActivateObjectFailed exception, the TP Framework will not complete the activation and will return the org.omg.CORBA.OBJECT_NOT_EXIST exception to the client. The client has presumably been warned about this possibility, since it knows about the iterator (or similar) pattern. The client must be prepared to restart the iteration.

Self-deactivation

Just as it is possible to preactivate an object with the process activation policy, it is possible to request the deactivation of an object with the process activation policy. The ability to preactivate and the ability to request deactivation are independent; regardless of how an object was activated, it can be deactivated explicitly.

A method in the application can request (via com.beasys.TP.deactivateEnabl e) that the object be deactivated. When com.beasys.TP.deactivateEnable is called and the object is subsequently deactivated, no guarantee is made that subsequent invocations on the CORBA object will result in reactivation in the same process as a previous activation. The association between the ObjectId and the servant exists from the activation of the CORBA object until one of the following events occurs: 1) the shutdown of the server process or 2) the application calls com.beasys.TP.deactivateEnable . After the association is broken, when the object is invoked again, it can be re-activated anywhere that is allowed by the WLE configuration parameters.

When a com.beasys.TP.deactivateEnable call is invoked, the object currently executing is deactivated after completion of the method in which the call is made. The object itself makes the decision that it should be deactivated. This is often done during a method call that acts as a "signoff" signal.

Saving and Restoring Object State

While CORBA objects are active, their state is contained in a servant. Unless an application uses com.beasys.TP.create_active_object_reference , state must be initialized when the object is first invoked (that is, the first time a method is invoked on a CORBA object after its object reference is created), and on subsequent invocations after they have been deactivated. While a CORBA object is deactivated, its state must be saved outside the process in which the servant was active. The object's state can be saved in shared memory, in a file, or in a database. Before a CORBA object is deactivated, its state must be saved; when it is activated, its state must be restored.

The programmer determines what constitutes an object's state and what must be saved before an object is deactivated, and restored when an object is activated.

USE OF CONSTRUCTORS FOR JAVA CORBA OBJECTS

The state of Java CORBA objects must not be initialized in the constructors for the servant classes. This is because the Java TP Framework may reuse an instance of a servant. No guarantee is made as to the timing of the creation of servant instances.

Transactions

The following sections provide information about transaction policies and how to use transactions.

Transaction Policies

Eligibility of CORBA objects to participate in global transactions is controlled by the transaction policies assigned to implementations at compile time. The following policies can be assigned.

Note: The activation policies are set in an Server Description file that is configured at OMG IDL compile time. For a description of the Server Description file, refer to Chapter 2, Server Description File.

Transaction Initiation

Transactions are initiated in one of two ways:

Transaction Termination

In general, the handling of the outcome of a transaction is the responsibility of the initiator. Therefore, the following is true:

The following behavior is enforced by the WLE system:

Transaction Suspend and Resume

The CORBA object must follow strict rules with respect to suspending and resuming a transaction within a method invocation. These rules and the error conditions that result from their violation are described in this section.

When a CORBA object method begins execution, the object can be in one of the following three states with respect to transactions:

Restrictions on Transactions

The following restrictions apply to WLE transactions:

Voting on Transaction Outcome

CORBA objects can affect transaction outcome during two stages of transaction processing:

Transaction Time-outs

When a transaction time-out occurs, the transaction is marked so that the only possible outcome is to roll back the transaction, and the org.omg.CORBA.TRANSACTION_ROLLEDBACK standard exception is returned to the client. Any attempts to send new requests will also fail with the org.omg.CORBA.TRANSACTION_ROLLEDBACK exception until the transaction has been aborted.

Java TP Framework Interfaces

The Java TP Framework supports the following interfaces:

Tobj_Servant Interface

The com.beasys.Tobj_Servant interface defines operations that allow a CORBA object to assist in the management of its state. Every implementation skeleton generated by the IDL compiler automatically inherits from the com.beasys.Tobj_Servant class. The com.beasys.Tobj_Servant class contains two virtual methods, activate_object and deactivate_object , that can be redefined by the programmer.

Whenever a request comes in for an inactive CORBA object, the object is activated and the activate_object method is invoked on the servant. When the CORBA object is deactivated, the deactivate_object method is invoked on the servant. The timing of deactivation is driven by the implementation's activation policy. When deactivate_object is invoked, the Java TP Framework passes in a reason code to indicate why the call was made.

Note: The activate_object and deactivate_object methods are the only methods that the Java TP Framework guarantees will be invoked for CORBA object activation and deactivation. The servant class constructor may or may not be invoked at activation time. Therefore, the server-application code must not do any state handling for CORBA objects in the constructor of the servant class.

Server Object

The com.beasys.Tobj.Server object provides default callback methods to initialize and release the server application. A new class that derives from the com.beasys.Tobj.Server class can be implemented that overrides the initialize and release methods with application-specific server initialization and termination logic.

TP Interface

The com.beasys.Tobj.TP interface supplies a set of service methods that can be invoked by application code. This is the only interface in the Java TP Framework that can safely be invoked by application code. All other interfaces have callback methods that are intended to be invoked only by system code.

The purpose of this interface is to provide high-level calls that application code can call, instead of calls to underlying APIs provided by the Portable Object Adapter (POA) and the BEA TUXEDO system. By using these calls, programmers can learn a simpler API and are spared the complexity of the underlying APIs.

The com.beasys.Tobj.TP interface implicitly uses two features of the WLE software that extend the CORBA APIs:

For information about the FactoryFinder object, see Chapter 5, FactoryFinder Interface. For more information about Factory-based routing, see the Administration Guide.

Usage Note

During server application initialization, the application constructs the object reference for an application factory. It then invokes the register_factory method, passing in the factory's object reference together with a factory id field. On server release (shutdown), the application uses the unregister_factory method to unregister the factory.

Error Conditions and Exceptions

The following paragraphs discuss error conditions and resulting exceptions.

Exceptions Raised by the Java TP Framework

The following exceptions are raised by the Java TP Framework and are returned to clients when error conditions occur in, or are detected by, the Java TP Framework:

CORBA.INTERNAL
CORBA.OBJECT_NOT_EXIST
CORBA.OBJ_ADAPTER
CORBA.INVALID_TRANSACTION
CORBA.TRANSACTION_ROLLEDBACK

Since the reason for these exceptions may be ambiguous, each time one of these exceptions is raised, the Java TP Framework also writes to the user log file a descriptive error message that explains the reason.

Exceptions in the Server Application Code

The following Java TP Framework callback methods are initiated by events other than client requests on the object:

com.beasys.Tobj_ServantBase.activate_object()
com.beasys.Tobj_ServantBase.deactivate_object()
com.beasys.Server.create_servant()

If exception conditions are raised in these methods, those exact exceptions are not reported back to the client. However, each of these methods is defined to raise an exception that includes a reason string. The Java TP Framework catches the exception raised by the callback and logs the reason string to the user log file. The Java TP Framework may raise an exception back to the client. Refer to the descriptions of the individual Java TP Framework callback methods for more information about these exceptions.

Example

For com.beasys.Tobj_ServantBase.deactivate_object() , the following line of code throws a DeactivateObjectFailed exception:

throw new com.beasys.TobjS.DeactivateObjectFailed( "deactivate
failed to save state!");

This message is appended to the user log file with a tag made up of the time (hhmmss), system name, process name, and process-id of the calling process. The tag is terminated with a colon. The preceding throw statement causes the following line to appear in the user log file:

151104.T1!simpapps.247: APPEXC: deactivate failed to save state!

Where 151104 is the time (3:11:04pm), T1 is the system name, simpapps is the process name, 247 is the process-id, and APPEXC identifies the message as an application exception message.

Exceptions and Transactions

Exceptions that are raised in either CORBA object methods or in TP Framework callback methods will not automatically cause a transaction to be rolled back unless the TP Framework started the transaction. It is up to the application code to call Current.rollback_only() if the condition that caused the exception to be raised should also cause the transaction to be rolled back.