![]() |
![]() |
BEA WebLogic Enterprise 4.2 Developer Center |
![]() HOME | SITE MAP | SEARCH | CONTACT | GLOSSARY | PDF FILES | WHAT'S NEW |
||
![]() C++ REFERENCE | TABLE OF CONTENTS | PREVIOUS TOPIC | NEXT TOPIC |
This chapter describes programming requirements for joint client/servers and the BEAWrapper Callbacks API.
For either a WLE client or joint client/server (that is, a client that can receive and process object invocations), the programmer writes the client main(). The WLE clients invoke operations on objects. In the case of DII, client code creates the DII Request object and then invokes one of two operations on the DII Request. In the case of static invocation, client code performs the invocation by performing what looks like an ordinary C++ invocation (which ends up calling code in the generated client stub). Additionally, the client programmer uses ORB interfaces defined by OMG, and WLE environmental objects that are supplied with the WLE software, to perform functions unique to WLE.
For WLE joint client/servers, the client code must be structured so that it can act as a server for callback WLE objects. Such clients do not use the TP Framework and are not subject to WLE system administration. Besides the programming implications, this means that joint client/servers do not have the same scalability and reliability as WLE servers, nor do they have the state management and transaction behavior available in the TP Framework. If a user wants to have those characteristics, the application must be structured in such a way that the object implementations are in a WLE server, rather than in a client.
The following sections describe the mechanisms you use to add callback support to a WLE client. In some cases, the mechanisms are contrasted with the WLE server mechanisms that use the TP Framework.
In a WLE server, you use the In contrast, for a WLE joint client/server (as for a WLE client), you create the main program and are responsible for all initialization. You do not need to provide a The specific initialization needed for a joint client/server is discussed below.
Servants (method code) for WLE joint client/servers are very similar to servants for WLE servers. All business logic is written the same way. The differences result from not using the TP Framework, which includes the Server, TP, and Tobj_ServantBase interfaces. Therefore, the main difference is that you use CORBA functions directly instead of indirectly through the TP Framework.
The Server interface is used in WLE servers to allow the TP Framework to ask the user to create a servant for an object when the ORB receives a request for that object. In WLE joint client/servers, the user program is responsible for creating a servant before any requests arrive; thus, the Server interface is not needed. Typically, the program creates a servant and then activates the object (using the servant and an Instead of invoking the TP interface to perform certain operations, client servants directly invoke the ORB and POA (which is what the TP interface does internally). Alternately, since much of the interaction with the ORB and POA is the same for all applications, for ease of use, the WLE client library provides a convenience wrapper object that does the same things, using a single operation. For a discussion of how to use the convenience wrapper object, see "Callback Object Models Supported" on page 9-4 and "Preparing Callback Objects Using BEAWrapper Callbacks" on page 9-7.
In a WLE client that supports callbacks, as well as in a WLE server, you write a C++ implementation class that inherits from the same skeleton class name generated by the IDL compiler (the The skeleton generated by the In a WLE server, the skeleton class inherits from the TP Framework class Tobj_ServantBase, which in turn inherits from the predefined PortableServer::ServantBase.
The inheritance tree for a callback object implementation in a joint client/server is different than that in a WLE server. The skeleton class does not inherit from the TP Framework class Tobj_ServantBase, but instead inherits directly from PortableServer::ServantBase. This behavior is achieved by specifying the Not having the Tobj_ServantBase class in the inheritance tree for a servant means that the servant does not have activate_object and deactivate_object methods. In a WLE server, these methods are called by the TP Framework to dynamically initialize and save a servant's state before invoking a method on the servant. For a WLE client that supports callbacks, you must write code that explicitly creates a servant and initializes a servant's state.
WLE software supports four kinds of callback objects and provides wrappers for the three that are most common. These objects correspond to three combinations of POA policies. The POA policies control both the types of objects and the types of object references that are possible.
The POA policies that are applicable are:
main()
uses WLE environmental objects to establish connections, set up security, and start transactions.
Main Program and Server Initialization
buildobjserver
command to create the main program for the server. That main program takes care of all WLE- and CORBA-related initialization of the server functions. The server main program allows the user to take part in server initialization and shutdown by making invocations on a user-written C++ object, the Server
class.
Server
object because you have complete control over the main program and you can provide initialization and shutdown code in any way that is convenient.
Servants
ObjectId
; the ObjectId
is possibly system generated) before handing a reference to the object. Such an object might be used to handle callbacks. Thus, the servant already exists and the object is activated before a request for the object arrives.
Servant Inheritance from Skeletons
idl
command). For example, given the IDL:
interface Hospital{ };
idl
command contains a "skeleton" class, POA_Hospital, that the user-written class inherits from, as in:
class Hospital_i : public POA_Hospital { ... };
-P
option in the idl
command.
Callback Object Models Supported
ObjectId
-the user or the system
ObjectId
is not assigned by the client application, but is a unique value assigned by the system. This type of object is useful for invocations that a client wants to receive only until the client terminates. (The corresponding POA LifeSpanPolicy value is TRANSIENT
and the IdAssignmentPolicy is SYSTEM_ID
.)
Note:
The Transient/UserId policy combination is not considered particularly important. It is possible for users to provide for themselves by using the POA in a manner analogous to either of the persistent cases, but the WLE wrappers do not provide special help to do so.
Note:
For WLE native joint client/servers, neither of the Persistent policies is supported, only the Transient policy.
To set up WLE callback objects using CORBA, the client must do the following:
Preparing Callback Objects Using CORBA
Assuming that the client already has obtained a reference to the ORB, performing this task takes four interactions with the ORB and the POA. It might look like the following for the Transient/SystemId model. In this model, only the Root POA is needed.
// Create a servant for the callback Object
Catcher_i* my_catcher_i = new Catcher_i();
// Get root POA reference and activate the POA
1 CORBA::Object_var oref =
orb->resolve_initial_references("RootPOA");
2 PortableServer::POA_var root_poa =
PortableServer::POA::_narrow(oref);
3 root_poa -> the_POAManager() -> activate();
4 PortableServer::objectId_var temp_Oid =
root_poa ->activate_object ( my_catcher_i );
5 oref = root_poa->create_reference_with_id(
temp_Oid, _tc_Catcher->id() );
6 Catcher_var my_catcher_ref = Catcher::_narrow( oref );
To use the Persistent/UserId model, there are some additional steps required when creating a POA. Further, the ObjectId
is specified by the client, and this requires more steps. It might look like the following.
Catcher_i* my_catcher_i = new Catcher_i();
const char* oid_str = "783";
1 PortableServer::objectId_var oid =
PortableServer::string_to_objectId(oid_str);
// Find root POA
2 CORBA::Object_var oref =
orb->resolve_initial_references("RootPOA");
3 PortableServer::POA_var root_poa =
PortableServer::POA::_narrow(oref);
// Create and activate a Persistent/UserId POA
4 CORBA::PolicyList policies(2);
5 policies.length(2);
6 policies[0] = root_poa->create_lifespan_policy(
PortableServer::PERSISTENT);
7 policies[1] = root_poa->create_id_assignment_policy(
PortableServer::USER_ID );
8 PortableServer::POA_var my_poa_ref =
root_poa->create_POA(
"my_poa_ref", root_poa->the_POAManager(), policies);
9 root_poa->the_POAmanager()->activate();
// Create object reference for callback Object
10 oref = my_poa_ref -> create_reference_with_id(
oid, _tc_Catcher->id());
11 Catcher_var my_catcher_ref = Catcher::_narrow( oref );
// activate object
12 my_poa_ref -> activate_object_with_id( oid, my_catcher_i );
// Make the call passing the callback ref
foo -> register_callback ( my_catcher_ref );
All the interfaces and operations described here are standard CORBA interfaces and operations.
Since the code required for callback objects is nearly identical for every client that supports callbacks, you may find it convenient to use the BEAWrappers provided in the library provided for joint client/servers.
The BEAwrappers are described in IDL, as follows.
Note:
These same wrappers are designed to be used for the WebLogic Enterprise V4.2 (Java) software, where a POA is not yet available, although aspects related to POAs do exist (notably, PortableServer.Servant
). For a discussion of these for the Java software, see Java Programming Reference.
// File: BEAWrapper
#ifndef _BEA_WRAPPER _IDL_
#define _BEA_WRAPPER _IDL_
#include <orb.idl>
#include <PortableServer.idll>
#pragma prefix "beasys.com"
moduleBEAWrapper
{
interfaceCallbacks
{
exception ServantAlreadyActive{ };
exception ObjectAlreadyActive { };
exception NotInRequest{ };
// set up transient callback Object
raises (ServantAlreadyActive);
// -- prepare POA, activate object, return objref
Object start_transient(
in PortableServer::Servant Servant,
in CORBA::RepositoryId rep_id)
// set up persistent/systemid callback Object
Object start_persistent_systemid(
in PortableServer::Servant servant,
in CORBA::Repository rep_id,
out string stroid)
raises (ServantAlreadyActive);
// reinstate set up for persistent/systemid
// callback object
Object restart_persistent_systemid(
in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id,
in string stroid)
raises (ServantAlreadyActive, ObjectAlreadyActive);
// set up persistent/userid callback Object
Object start_persistent_userid(
in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id,
in string stroid)
raises (ServantAlreadyActive, ObjectAlreadyActive);
// stop servicing a particular callback Object
// with the given servant
void stop_object( in PortableServer::Servant servant);
//shutdown Stop all callback Object processing
void stop_all_objects();
// get oid string for the current request
;
string get_string_oid() raises (NotInRequest)
};
}
#endif /* _BEA_WRAPPER _IDL_ */
The BEAwrappers are described in C++ as follows:
C++ Declarations (in beawrapper.h)
#ifndef _BEAWRAPPER_H_
#define _BEAWRAPPER_H_
#include <PortableServer.h>
class BEAWrapper{
class Callbacks{
public:
Callbacks (CORBA::ORB_ptr init_orb);
CORBA::Object_ptr start_transient (
PortableServer::Servant servant,
const char * rep_id);
CORBA::Object_ptr start_persistent_systemid (
PortableServer::Servant servant,
const char * rep_id,
char * & stroid);
CORBA::Object_ptr restart_persistent_systemid (
PortableServer::Servant servant,
const char * rep_id,
const char * stroid);
CORBA::Object_ptr start_persistent_userid (
PortableServer::Servant servant,
const char * rep_id,
const char * stroid);
void stop_object(PortableServer::Servant servant);
char* get_string_oid ();
void stop_all_objects();
~Callbacks();
private:
static CORBA::ORB_var orb_ptr;
static PortableServer::POA_var root_poa;
static PortableServer::POA_var trasys_poa;
static PortableServer::POA_var persys_poa;
static PortableServer::POA_var peruser_poa;
};
};
#endif // _BEAWRAPPER_H_
The description of each operation in the BEAWrapper::Callbacks
interface follows, in the order declared above.
Synopsis
Returns a reference to the Callbacks interface.
C++ Binding
BEAWrapper::Callbacks( CORBA::ORB_ptr init_orb);
Java Binding
public Callbacks(org.omg.CORBA.Object init_orb);
Argument
init_orb
- The ORB to be used for all further operations.
Return Value
A reference to the Callbacks object.
Description
The constructor returns a reference to the Callbacks interface. Only one such object should be created for the process, even if multiple threads are used. Using more than one such object will result in undefined behavior.
Exception
CORBA::IMP_LIMIT
- The
BEAWrapper::Callbacks
class has already be instantiated with an ORB pointer. Only one instance of this class can be used in a process. Users who need additional flexibility should use the POA directly.
Synopsis
Activates an object, sets the ORB and the POA to the proper state, and returns an object reference to the activated object.
IDL
Object start_transient( in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id)
raises ( ServantAlreadyActive );C++ Binding
CORBA::Object_ptr start_transient(
PortableServer::Servant servant,
const char* rep_id);Java Binding
org.omg.CORBA.Object start_transient(
org.omg.PortableServer.Servant servant,
java.lang.String rep_id);Arguments
servant
- An instance of the C++ implementation class for the interface.
rep_id
- The repository
id
of the interface.Return Value
CORBA::Object_ptr
- A reference to the object that was created with the
ObjectId
generated by the system and therep_id
provided by the user. The object reference will need to be converted to a specific object type by invoking the_narrow()
operation defined for the specific object. The caller is responsible for releasing the object when the conversion is done.Description
This operation performs the following actions:
- Activates an object using the
Servant
supplied to service objects of the typerep_id
, using anObjectId
generated by the system.
- Sets the ORB and the POA into the state in which they will accept requests on that object.
ServantAlreadyActive
- The servant is already being used for a callback. A servant can be used only for a callback with a single
ObjectId
. To receive callbacks on objects containing differentObjectId
s, you must create different servants and activate them separately. The same servant can be re-used only if astop_object
operation tells the system to stop using the servant for its originalObjectId
.CORBA::BAD_PARAM
- The repository ID was a null string or the servant was a null pointer.
Synopsis
Activates an object, sets the ORB and the POA to the proper state, sets the output parameter
stroid
, and returns an object reference to the activated object.
IDL
Objectstart_persistent_systemid
(
in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id,
out string stroid)
raises ( ServantAlreadyActive );C++ Binding
CORBA::Object_ptrstart_persistent_systemid
(
PortableServer::Servant servant,
const char* rep_id,
char*& stroid);
Java Binding
org.omg.CORBA.Objectstart_persistent_systemid
(
org.omg.PortableServer.Servant servant,
java.lang.String rep_id,
java.lang.String stroid);Arguments
servant
- An instance of the C++ implementation class for the interface.
rep_id
- The repository id of the interface.
stroid
- This argument is set by the system and is opaque to the user. The client will use it when it reactivates the object at a later time (using
restart_persistent_systemid
), most likely after the client process has terminated and restarted.Return Value
CORBA::Object_ptr
- An object reference created with the
ObjectId
generated by the system and therep_id
provided by the user. The object reference will need to be converted to a specific object type by invoking the_narrow()
operation defined for the specific object. The caller is responsible for releasing the object when the conversion is done.Description
This operation performs the following actions:
- Activates an object using the
Servant
supplied to service objects of the typerep_id
, using anObjectId
generated by the system.
- Sets the ORB and the POA into the state in which they will accept requests on that object.
- Sets the output parameter
stroid
to the stringified version of anObjectId
assigned by the system.
ServantAlreadyActive
- The servant is already being used for a callback. A servant can be used only for a callback with a single
ObjectId
. To receive callbacks on objects containing differentObjectIds
, you must create different servants and activate them separately. The same servant can be re-used only if astop
operation tells the system to stop using the servant for its originalObjectId
.CORBA::BAD_PARAMETER
- The repository ID was a null string or the servant was a null pointer.
CORBA::IMP_LIMIT
- In addition to other system reasons for this exception, a reason unique to this situation is that the joint client/server was not initialized with a port number; therefore, a persistent object reference cannot be created.
Synopsis
Activates an object, sets the ORB and the POA to the proper state, and returns an object reference to the activated object.
IDL
Objectrestart_persistent_systemid
(
in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id,
in string stroid)
raises (ServantAlreadyActive, ObjectAlreadyActive);C++ Binding
CORBA::Object_ptrrestart_persistent_systemid(
PortableServer::Servant servant,
const char* rep_id
const char* stroid);
Java Binding
org.omg.CORBA.Objectrestart_persistent_systemid
(
org.omg.PortableServer.Servant servant,
java.lang.String rep_id,
java.lang.String stroid);Arguments
servant
- An instance of the C++ implementation class for the interface.
rep_id
- The repository id of the interface.
stroid
- The stringified version of the ObjectId provided by the user to be set in the object reference being created. It must have been returned from a previous call on
start_persistent_systemid
.Return Value
CORBA::Object_ptr
- An object reference created with the stringified ObjectId
stroid
and therep_id
provided by the user. The object reference will need to be converted to a specific object type by invoking the_narrow()
operation defined for the specific object. The caller is responsible for releasing the object when done.Description
This operation performs the following actions:
- Activates an object using the
Servant
supplied to service objects of the typerep_id
, using the suppliedstroid
(a stringified ObjectId), which must have been obtained by a previous call onstart_persistent_systemid
.
- Sets the ORB and the POA into the state in which they will accept requests on that object.
- Returns an object reference to the object activated.
- The re-activation would be done using the "restart_persistent_systemid" method.
ServantAlreadyActive
- The servant is already being used for a callback. A servant can be used only for a callback with a single
ObjectId
. To receive callbacks on objects containing differentObjectId
s, you must create different servants and activate them separately. The same servant can be re-used only if astop_object
operation tells the system to stop using the servant for its originalObjectId
.ObjectAlreadyActive
- The stringified ObjectId is already being used for a callback. A given ObjectId can have only one servant associated with it. If you wish to change to a different servant, you must first invoke
stop_object
with the servant currently in use.CORBA::BAD_PARAM
- The repository id was a null string or the servant was a null pointer or the ObjectId supplied was not previously assigned by the system.
CORBA::IMP_LIMIT
- In addition to other system reasons for this exception, a reason unique to this situation is that the joint client/server was not initialized with a port number; therefore, a persistent object reference cannot be created.
Synopsis
Activates an object, sets the ORB and the POA to the proper state, and returns an object reference to the activated object.
IDL
Objectstart_persistent_userid(
portableServer::Servant a_servant,
in CORBA::RepositoryId rep_id,
in string stroid)
raises ( ServantAlreadyActive, ObjectAlreadyActive );C++ Binding
CORBA::Object_ptr start_persistent_userid (
PortableServer::Servant servant,
const char* rep_id,
const char* stroid);Java Binding
org.omg.CORBA.Objectstart_persistent_userid
(
org.omg.PortableServer.Servant servant,
java.lang.String rep_id,
java.lang.String stroid);Arguments
servant
- An instance of the C++ implementation class for the interface.
rep_id
- The repository id of the interface.
stroid
- The stringified version of an
ObjectId
provided by the user to be set in the object reference being created. Thestroid
holds application-specific data and is opaque to the ORB.Return Value
CORBA::Object_ptr
- An object reference created with the stringified ObjectId
stroid
and therep_id
provided by the user. The object reference will need to be converted to a specific object type by invoking the_narrow()
operation defined for the specific object. The caller is responsible for releasing the object when the conversion is done.Description
This operation performs the following actions:
- Activates an object using the
Servant
supplied to service objects of the typerep_id
, using the object idstroid
.
- Sets the ORB and the POA into the state in which they will accept requests on that object.
ServantAlreadyActive
- The servant is already being used for a callback. A servant can be used only for a callback with a single
ObjectId
. To receive callbacks on objects containing differentObjectId
s, you must create different servants and activate them separately. The same servant can be re-used only if astop_object
operation tells the system to stop using the servant for its originalObjectId
.ObjectAlreadyActive
- The stringified
ObjectId
is already being used for a callback. A givenObjectId
can have only one servant associated with it. If you wish to change to a different servant, you must first invokestop_object
with the servant currently in use.CORBA::BAD_PARAM
- The repository ID was a null string or the servant was a null pointer.
CORBA::IMP_LIMIT
- In addition to other system reasons for this exception, a reason unique to this situation is that the joint client/server was not initialized with a port number; therefore, a persistent object reference cannot be created.
Synopsis
Tells the ORB to stop accepting requests on the object that is using the given servant.
IDL
void stop_object( in PortableServer::Servant servant);C++ Binding
voidstop_object
(PortableServer::Servant servant);Java Binding
voidstop_object
(org.omg.PortableServer.Servant servant);Argument
servant
- An instance of the C++ implementation class for the interface. The association between this servant and its
ObjectId
will be removed from the Active Object Map.Description
This operation tells the ORB to stop accepting requests on the given servant. It does not matter what state the servant is in, activated or deactivated; no error is reported.
Return Value
None.
Exceptions
None.
Synopsis
Tells the ORB to stop accepting requests on all servants.
IDL
void stop_all_objects ();
C++ Binding
void stop_all_objects ();
Java Binding
void stop_all_objects ();
Return Value
None.
Description
This operation tells the ORB to stop accepting requests on all servants that have been set up in this process.
Usage Note
If a client calls the
ORB::shutdown
method, then it must not subsequently callstop_all_objects
.Exceptions
None.
Synopsis
Requests the string version of the
ObjectId
of the current request.IDL
string get_string_oid() raises (NotInRequest);
C++ Binding
char* get_string_oid();
Java Binding
java.lang.String get_string_oid();
Return Value
char*
- The string version of the
ObjectId
of the current request. This is the string that was supplied when the object reference was created. The string is meaningful to users only in the case when the object reference was created by the start_persistent_userid function. (That is, theObjectId
created by start_transient and start_persistent_systemid were created by the ORB and has no relationship to the user application.)Description
This operation returns the string version of the
ObjectId
of the current request.Exceptions
NotInRequest
- The function was called when the ORB was not in the context of a request (that is, not while the ORB was servicing a request in method code). Do not call this function from client code. It is legal only during the execution of a method of the callback object (that is, the servant).
Synopsis
Destroys the callback object.
C++ Binding
BEAWrapper::~Callbacks( );
Java Binding
public ~Callbacks();
Arguments
None.
Return Value
None.
Description
This destructor destroys the callback object.
Usage Note
If a client wants to get rid of the wrapper, but not shut down the ORB, then the client must call the
stop_all_objects
method.Exceptions
None.