VisiBroker for Java Developer’s Guide : Using the Object Activation Daemon (OAD)

Using the Object Activation Daemon (OAD)
This section discusses how to use the Object Activation Daemon (OAD).
Automatic activation of objects and servers
The Object Activation Daemon (OAD) is the VisiBroker implementation of the Implementation Repository. The Implementation Repository provides a runtime repository of information about the classes a server supports, the objects that are instantiated, and their IDs. In addition to the services provided by a typical Implementation Repository, the OAD is used to automatically activate an implementation when a client references the object. You can register an object implementation with the OAD to provide this automatic activation behavior for your objects.
Object implementations can be registered using a command-line interface (oadutil). There is also a VisiBroker ORB interface to the OAD, described in “IDL interface to the OAD”. In each case, the repository ID, object name, the activation policy, and the executable program representing the implementation must be specified.
Note
You can use the VisiBroker OAD to instantiate servers generated with VisiBroker for Java and C++.
The OAD is a separate process that only needs to be started on those hosts where object servers are to be activated on demand.
Locating the Implementation Repository data
Activation information for all object implementations registered with the OAD are stored in the Implementation Repository. By default, the Implementation Repository data is stored in a file named impl_rep in the <install_dir>/adm/impl_dir directory.
Activating servers
The OAD activates servers in response to client requests. VisiBroker clients and non-VisiBroker IIOP-compliant clients can activate servers through the OAD.
Any client that uses the IIOP protocol can activate a VisiBroker server when that server's reference is used. The server's exported Object Reference points to the OAD and the client can be forwarded to the spawned server in accordance with the rules of IIOP. To allow true persistence of the server's object references (such as through a Name Service), the OAD must always be started on the same port. For example, to start the OAD on port 16050, enter the following:
prompt> oad -VBJprop vbroker.se.iiop_tp.scm.iiop_tp.listener.port=16050
Note
Port 16000 is the default port, but it can be changed by setting the listener.port property.
Using the OAD
The OAD is an optional feature that allows you to register objects that are to be started automatically when clients attempt to access them. Before starting the OAD, you should first start the Smart Agent. For more information, see “Starting a Smart Agent (osagent)”.
Starting the OAD
Windows
To start the OAD:
Use the oad.exe located in <install_dir>\bin\
or
prompt> oad
or
prompt> oad -C
The oad command accepts the following command line arguments:
-path <path>
-filename <repository_filename>
Specifies the name of the Implementation Repository. If you do not specify it, the default is impl_rep. This overrides any user environment variable settings.
-timeout <#_of_seconds>
Specifies the amount of time the OAD will wait for a spawned server process to activate the requested VisiBroker ORB object. The default time-out is 20 seconds. Set this value to 0 (zero) if you wish to wait indefinitely. If a spawned server process does not activate the requested object within the time-out interval, the OAD will kill the spawned process and the client will see a CORBA::NO IMPLEMENT exception. Turn on the verbose option to see more detailed information.
-IOR <IOR_filename>
When the OAD is started with the -readonly option, no changes can be made to the registered objects. Attempts to register or unregister objects will return an error. The -readonly option is usually used after you've made changes to the Implementation Repository, and have restarted the OAD in readonly mode to the prevent any additional changes.
The OAD is installed as Windows Service, allowing you to control it with the Service Manager provided with Windows.
UNIX
To start the OAD enter the following command:
prompt> oad &
Using the OAD utilities
The oadutil commands provide a way for you to manually register, unregister, and list the object implementations available on your VisiBroker system. The oadutil commands are implemented in Java and use a command line interface. Each command is accessed by invoking the oadutil command, passing the type of operation to be performed as the first argument.
Note
An object activation daemon process (oad) must be started on at least one host in your network before you can use the oadutil commands.
The oadutil command has the following syntax:
oadutil {list|reg|unreg} [options]
The options for this tool vary, depending on whether you specify list, reg or unreg.
Converting interface names to repository IDs
Interface names and repository IDs are two ways of representing the type of interface the activated object should implement. All interfaces defined in IDL are assigned a unique repository identifier. This string is used to identify a type when communicating with the Interface Repository, the OAD, and most calls to the VisiBroker ORB itself.
When registering or unregistering an object with the OAD, the oadutil commands allow you to specify either an object's IDL interface name or its repository id.
An interface name is converted to a repository ID as follows:
1
Prepend “IDL:” to the interface name.
2
3
Append “:1.0” to the interface name.
For example, the IDL interface name
::Module1::Module2::IntfName
would be converted to the following repository ID:
IDL:Module1/Module2/IntfName:1.0
The #pragma ID and #pragma prefix mechanisms can be used to override the default generation of repository ID's from interface names. If the #pragma ID mechanism is used in user-defined IDL files to specify non-standard repository IDs, the conversion process outlined above will not work. In these cases, you must use -r repository ID argument and specify the object's repository ID.
To obtain the repository id of the object implementation's most derived interface in Java, use the method java: <interface_name>Helper.id() defined for all CORBA objects.
Listing objects with oadutil list
The oadutil list utility allows you to list all VisiBroker ORB object implementations registered with the OAD. The information for each object includes:
The oadutil list command returns all VisiBroker ORB object implementations registered with the OAD. Each OAD has its own Implementation Repository database where the registration information is stored.
Note
An OAD process must be started on at least one host in your network before you can use the oadutil list command.
The oadutil list command has the following syntax:
oadutil list [options]
The oadutil list command accepts the following command line arguments:
Note: All communications with the VisiBroker ORB reference an object's repository id instead of the interface name. For more information about the conversion performed when specifying an interface name, see the “Converting interface names to repository IDs” section.
Lists the implementation information of a specific repository id. See “Converting interface names to repository IDs” for details on specifying repository IDs. Only one of the following options may be specified at a particular time: -i, -r, -s, or -poa.
The following is an example of a local list request, specifying an interface name and object name:
oadutil list -i Bank::AccountManager -o MFBank
The following is an example of a remote list request, specifying a host IP address:
oadutil list -h 206.64.15.198
Registering objects with oadutil
The oadutil command can be used to register an object implementation from the command line or from within a script. The parameters are either the interface name and object name, the service name, or the POA name, and path name to the executable that starts the implementation. If the activation policy is not specified, the shared server policy will be used by default. You may write an implementation and start it manually during the development and testing phases. When your implementation is ready to be deployed, you can simply use oadutil to register your implementation with the OAD.
Notes
An oad process must be started on at least one host in your network before you can use the oadutil reg command.
The oadutil reg command has the following syntax:
oadutil reg [options]
The oadutil reg command accepts the following command-line arguments:
-poa <poa_name>
Specifies the full path of an executable file that must create and register an object that matches the
-o/-r/-s/-poa arguments. Applications registered with the -cpp argument must be stand-alone executables.
Specifies the full name of a Java class containing a main routine. This application must create and register an Object that matches the -o/-r/-s/-poa argument. Classes registered with the -java argument will be executed with the command vbj <full_classname>.
Specifies the arguments to be passed to the spawned executable as command-line arguments. Arguments can be passed with multiple -a (arg) parameters. They will be propagated in order to create the spawned executable.
Specifies environment variables to be passed to the spawned executable. Arguments can be passed with multiple -e (env) parameters. They will be propagated in order to create the spawned executable.
Specifies the activation policy of the spawned objects. The default policy is SHARED_SERVER. Shared: Multiple clients of a given object share the same implementation. Only one server is activated by an OAD at a particular time. Unshared: Only one client of a given implementation will bind to the activated server. If multiple clients wish to bind to the same object implementation, a separate server is activated for each client application. A server exits when its client application disconnects or exits.
Example: Registering a POA
The following command registers a POA with the OAD.
oadutil reg -e vbroker.oad.locateAlways=true -poa /bank_agent_poa -java Server -verbose -p unshared
Specifying vbroker.oad.locateAlways as true ensures that the client can locate the POA; see “OAD properties” for details of this property. The instance name is /bank_agent_poa. The object has the unshared policy, by which it will be terminated when the requesting client breaks its connection to the spawned server.
Example: Specifying repository ID
The following command will register with the OAD the VisiBroker program factory. It will be activated upon request for objects of repository ID IDL:ehTest/Factory:1.0 (which corresponds to the interface name ehTest::Factory). The instance name of the object to be activated is ReentrantServer, and that name is also passed to the spawned executable as a command-line argument. This server has the unshared policy, by which it will be terminated when the requesting client breaks its connection to the spawned server.
prompt> oadutil reg -e vbroker.oad.locateAlways=true -r IDL:ehTest/Factory:1.0
-o ReentrantServer -java factory_r -a ReentrantServer -p unshared
Note
In the example above, the specified Java class must be found in the CLASSPATH.
Example: Specifying IDL interface name
The following command will register the VisiBroker Server class with the OAD. In this example, the specified class must activate an object of repository ID IDL:Bank/AccountManager:1.0 (corresponding to the interface name IDL name Bank::AccountManager) and instance name CreditUnion. The server will be started with unshared policy, ensuring that it will terminate when the requesting client breaks its connection. The server is also passed with an environment variable DEBUG=1 when it is first started by the client.
prompt> oadutil reg -i Bank::AccountManager -o CreditUnion -java Server
-a CreditUnion -p unshared -e DEBUG=1 -e vbroker.oad.locateAlways=true
Note
In the previous example, the specified Java class must be found in the CLASSPATH.
The previous registration tells the OAD to execute the following command when spawning the requested server:
vbj -DDEBUG=1 Server CreditUnion
Remote registration to an OAD
To register an implementation with an OAD on a remote host, use the -h argument to oadutil reg.
The following is an example of how to perform a remote registration to an OAD on Windows from a UNIX shell. The double backslashes are necessary to avoid having the shell interpret the backslashes before passing them to oadutil.
prompt> oadutil reg -r IDL:Library:1.0 Harvard \
-java c:\\vbroker\\examples\\library\\libsrv -p shared -h 100.64.15.198
Using the OAD without using the Smart Agent
To access a server using the OAD without involving the Smart Agent, use the property vbroker.orb.activationIOR to indicate the OAD's IOR to oadutil and to the server.
For example, let us assume that the OAD's IOR is located in the e:/adm dir (on Windows), and you want to run the bank_portable example that is included (in the examples/basic/bank_portable directory) with with the product. To access this server without using the Smart Agent:
1
Start the OAD: the classpath visible to OAD must include the Server's classpath. The command is:
prompt>start oad -VBJprop vbroker.agent.enableLocator=false -verbose
2
Register the server using oadutil: the command is:
prompt> oadutil -VBJprop vbroker.orb.activationIOR=file:
///e:/adm/oadj.ior -VBJprop
vbroker.agent.enableLocator=false reg -i Bank::AccountManager
-o BankManager -java Server
3
Generate the Server's IOR: when the server is started it will write out it's IOR into a file. Terminate the server once it is running, so that the launching of the server by the OAD can be demonstrated. The command is:
prompt> vbj -Dvbroker.orb.activationIOR=file:///e:/adm/oadj.ior Server
4
Run the Client: make sure the OAD is running, then use the command:
prompt> vbj -Dvbroker.agent.enableLocator=false Client
Using the OAD with the Naming Service
OAD facilitates the use of the Naming Service for bootstrapping. In the above section, the Smart Agent was not used, and the client needed to obtain the server's IOR file. This bootstrapping can be achieved using the Naming Service instead, as illustrated in the following steps.
1
prompt>oad -verbose -VBJprop vbroker.orb.initRef=NameService=corbaloc::myhost:1111/NameService
2
Register the server with the OAD. Note the use of the -cos_name parameter which indicates to the OAD that this server should be automatically bound to the Naming Service.
prompt>oadutil -VBJprop vbroker.orb.activationIOR=file:
///e:/adm/oadj.ior -VBJprop
vbroker.agent.enableLocator=false reg -i Bank::AccountManager
-o BankManager -cos_name simple_test -cpp Server/pre>
prompt>oadutil -VBJprop vbroker.orb.activationIOR=file:
///e:/adm/oadj.ior -VBJprop
vbroker.agent.enableLocator=false reg -i Bank::AccountManager
-o BankManager -cos_name simple_test -java Server
-e vbroker.oad.locateAlways=true
3
prompt>org.omg.CORBA.Object server=
rootCtx.resolve(new NameComponent[] {new NameComponent("simple_test","")});
Note that the OAD automatically created a binding for the server in the Naming Service because the -cos_name parameter was used.
Distinguishing between multiple instances of an object
Your implementation can use ReferenceData to distinguish between multiple instances of the same object. The value of the reference data is chosen by the implementation at object creation time and remains constant during the lifetime of the object. The ReferenceData typedef is portable across platforms and VisiBroker ORBs.
Setting activation properties using the CreationImplDef class
The CreationImplDef class contains the properties the OAD requires to activate a VisiBroker ORB object: path_name, activation_policy, args, and env. The following sample shows the CreationImplDef struct.
The path_name property specifies the exact path name of the executable program that implements the object. The activation_policy property represents the server's activation policy, discussed in “Example of object creation and registration”. The args and env properties represent command line arguments and environment settings for the server.
module extension {
...
enum Policy {
SHARED_SERVER,
UNSHARED_SERVER
};
struct CreationImplDef {
CORBA::RepositoryId repository_id;
string object_name;
CORBA::ReferenceData id;
string path_name;
Policy activation_policy;
CORBA::StringSequence args;
CORBA::StringSequence env;
};
...
};
Dynamically changing an ORB implementation
The sample below shows the change_implementation() method which can be used to dynamically change an object's registration. You can use this method to change the object's activation policy, path name, arguments, and environment variables.
module Activation
{
...
void change_implementation(in extension::CreationImplDef old_info,
in extension::CreationImplDef new_info)
raises ( NotRegistered, InvalidPath, IsActive );
...
};
Caution
Although you can change an object's implementation name and object name with the change_implementation() method, you should exercise caution. Doing so will prevent client programs from locating the object with the old name.
OAD Registration using OAD::reg_implementation
Instead of using the oadutil reg command manually or in a script, VisiBroker allows client applications to use the OAD::reg_implementation operation to register one or more objects with the activation daemon. Using this operation results in an object implementation being registered with the OAD and the osagent. The OAD will store the information in the Implementation Repository, allowing the object implementation to be located and activated when a client attempts to bind to the object.
module Activation {
...
typedef sequence<ObjectStatus> ObjectStatus List;
...
typedef sequence<ImplementationStatus> ImplStatusList;
...
interface OAD {
// Register an implementation.
Object
reg_implementation(in extension::CreationImplDef impl)
raises (DuplicateEntry, InvalidPath);
}
}
The CreationImplDef struct contains the properties the OAD requires. The properties are repository_id, object_name, id, path_name, activation_policy, args, and env. Operations for setting and querying their values are also provided. These additional properties are used by the OAD to activate an VisiBroker ORB object.
struct CreationImplDef {
CORBA::RepositoryId repository_id;
string object_name;
CORBA::ReferenceData id;
string path_name;
Policy activation_policy;
CORBA::StringSequence args;
CORBA::StringSequence env;
};
The path_name property specifies the exact path name of the executable program that implements the object. The activation_policy property represents the server's activation policy. The args and env properties represent optional arguments and environment settings to be passed to the server.
Example of object creation and registration
The following code sample shows how to use the CreationImplDef class and the OAD.reg_implementation() method to register a server with the OAD. This mechanism may be used in a separate, administrative program, not necessarily in the object implementation itself. If used in the object implementation, these tasks must be performed prior to activating the object implementation.
Creating an ORB object and registering with the OAD:
// Register.java
import com.inprise.vbroker.Activation.*;
import com.inprise.vbroker.extension.*;
public class Register{
public static void main(String[] args) {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// Locate an OAD
try {
OAD anOAD =
OADHelper.bind(orb);
// Create an ImplDef
CreationImplDef _implDef = new
com.inprise.vbroker.extension.CreationImplDef();
_implDef.repository_id = "IDL:Bank/AccountManager:1.0";
_implDef.object_name = "BankManager";
_implDef.path_name = "vbj";
_implDef.id = new byte[0];
_implDef.activation_policy =
com.inprise.vbroker.extension.Policy.SHARED_SERVER;
_implDef.env = new String[1];
         _implDef.env[0] = "vbroker.oad.locateAlways=true";
String[] str = new String[1];
str[0] = "Server";
_implDef.args = str;
try {
anOAD.reg_implementation(_implDef);
} catch (Exception e) {
System.out.println("Caught " + e);
}
}
catch (org.omg.CORBA.NO_IMPLEMENT e) {
}
}
}
Arguments passed by the OAD
When the OAD starts an object implementation it passes all of the arguments that were specified when the implementation was registered with the OAD.
Un-registering objects
When the services offered by an object are no longer available or temporarily suspended, the object should be unregistered with the OAD. When the VisiBroker ORB object is unregistered, it is removed from the Implementation Repository. The object is also removed from the Smart Agent's dictionary. Once an object is unregistered, client programs will no longer be able to locate or use it. In addition, you will be unable to use the OAD.change_implementation() method to change the object's implementation. As with the registration process, un-registering may be done either at the command line or programmatically.
Un-registering objects using the oadutil tool
The oadutil unreg command allows you to unregister one or more object implementations registered with the OAD. Once an object is unregistered, it can no longer be automatically activated by the OAD if a client requests the object. Only objects that have been previously registered via the oadutil reg command may be unregistered with oadutil unreg.
If you specify only an interface name, all VisiBroker ORB objects associated with that interface will be unregistered. Alternatively, you may identify a specific VisiBroker ORB object by its interface name and object name. When you unregister an object, all processes associated with that object will be terminated.
Note
An oad process must be started on at least one host in your network before you can use the oadutil reg command.
The oadutil unreg command has the following syntax:
oadutil unreg [options]
The options for the oadutil unreg command accepts the following command line arguments:
Unregisters the POA registered using oadutil reg -poa <POA_name>.
Unregistration example
The oadutil unreg utility unregisters one or more VisiBroker ORB objects from these three locations:
The following is an example of how to use the oadutil unreg command. It unregisters the implementation of the Bank::AccountManager named MyBank from the local OAD.
oadutil unreg -i Bank::AccountManager -o MyBank
Unregistering with the OAD operations
An object's implementation can use any one of the operations or attributes in the OAD interface to unregister a VisiBroker ORB object.
Use this operation to un-registered all implementations. Unless destroyActive is set to true, all active implementations continue to execute. For backward compatibility, unregister_all() is not destructive; it is equivalent to invoking unregister_all_destroy(false).
The following is an example of an OAD unregistered operation:
module Activation {
...
interface OAD {
...
void
unreg_implementation(in CORBA::RepositoryId repId,
in string object_name)
raises(NotRegistered);
...
}
}
Displaying the contents of the Implementation Repository
You can use the oadutil tool to list the contents of a particular Implementation Repository. For each implementation in the repository the oadutil tool lists all the object instance names, the path name of the executable program, the activation mode and the reference data. Any arguments or environment variables that are to be passed to the executable program are also listed.
IDL interface to the OAD
The OAD is implemented as a VisiBroker ORB object, allowing you to create a client program that binds to the OAD and uses its interface to query the status of objects that have been registered. The sample below shows the IDL interface specification for the OAD.
module Activation
{
enum state {
ACTIVE,
INACTIVE,
WAITING_FOR_ACTIVATION
};
struct ObjectStatus {
long unique_id;
State activation_state;
Object objRef;
};
typedef sequence<ObjectStatus> ObjectStatusList;
struct ImplementationStatus {
extension::CreationImplDef impl;
ObjectStatusList status;
};
typedef sequence<ImplementationStatus> ImplStatusList;
exception DuplicateEntry {};
exception InvalidPath {};
exception NotRegistered {};
exception FailedToExecute {};
exception NotResponding {};
exception IsActive {};
exception Busy {};
interface OAD {
Object reg_implementation( in extension::CreationImplDef impl)
raises (DuplicateEntry, InvalidPath);
extension::CreationImplDef get_implementation(
in CORBA::RepositoryId repId,
in string object_name)
raises ( NotRegistered);
void change_implementation(in extension::CreationImplDef old_info,
in extension::CreationImplDef new_info)
raises (NotRegistered,InvalidPath,IsActive);
attribute boolean destroy_on_unregister;
void unreg_implementation(in CORBA::RepositoryId repId,
in string object_name)
raises ( NotRegistered );
void unreg_interface(in CORBA::RepositoryId repId)
raises ( NotRegistered );
void unregister_all();
ImplementationStatus get_status(in CORBA::RepositoryId repId,
in string object_name)
raises ( NotRegistered);
ImplStatusList get_status_interface(in CORBA::RepositoryId repId)
raises (NotRegistered);
ImplStatusList get_status_all();
};