VisiBroker for Java Developer’s Guide : Client basics

Client basics
This section describes how client programs access and use distributed objects.
Initializing the VisiBroker ORB
The Object Request Broker (ORB) provides a communication link between the client and the server. When a client makes a request, the VisiBroker ORB locates the object implementation, activates the object if necessary, delivers the request to the object, and returns the response to the client. The client is unaware whether the object is on the same machine or across a network.
You are advised to create only one single instance of the VisiBroker ORB per process as the ORB can use a significant amount of system resources.
Though much of the work done by the VisiBroker ORB is transparent to you, your client program must explicitly initialize the VisiBroker ORB. VisiBroker ORB options, described in “Programmer tools for Java”, can be specified as command-line arguments. To ensure these options take effect you will need to pass the supplied args argument to ORB.init. The code samples below illustrate the VisiBroker ORB initialization.
public class Client {
public static void main (String[]
args) {
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
...
}
Binding to objects
A client program uses a remote object by obtaining a reference to the object. Object references are usually obtained using the <interface>Helper's bind() method. The VisiBroker ORB hides most of the details involved with obtaining the object reference, such as locating the server that implements the object and establishing a connection to that server.
Action performed during the bind process
When the server process starts, it performs ORB.init() and announces itself to Smart Agents on the network.
When your client program invokes the bind() method, the VisiBroker ORB performs several functions on behalf of your program.
The VisiBroker ORB contacts the Smart Agent to locate an object implementation that offers the requested interface. If an object name is specified when bind() is invoked, that name is used to further qualify the directory service search. The Object Activation Daemon (OAD), described in “Using the Object Activation Daemon (OAD)”, may be involved in this process if the server object has been registered with the OAD.
Figure 17
Note
Your client program will never invoke a constructor for the server class. Instead, an object reference is obtained by invoking the static bind() method.
Bank.AccountManager manager =
Bank.AccountManagerHelper.bind(orb,
"/bank_agent_poa",
"BankManager".getBytes());
Invoking operations on an object
Your client program uses an object reference to invoke an operation on an object or to reference data contained by the object. “Manipulating object references” describes the variety of ways that object references can be manipulated.
The following example shows how to invoke an operation using an object reference:
// Invoke the balance operation.
System.out.println("The balance in Account1: $" + account1.balance());
Manipulating object references
The bind() method returns a reference to a CORBA object to your client program. Your client program can use the object reference to invoke operations on the object that have been defined in the object's IDL interface specification. In addition, there are methods that all VisiBroker ORB objects inherit from the class org.omg.CORBA.Object that you can use to manipulate the object.
Converting a reference to a string
VisiBroker provides a VisiBroker ORB class with methods that allow you to convert an object reference to a string or convert a string back into an object reference. The CORBA specification refers to this process as stringification.
A client program can use the object_to_string method to convert an object reference to a string and pass it to another client program. The second client may then de‑stringify the object reference, using the string_to_object method, and use the object reference without having to explicitly bind to the object.
Note
Locally-scoped object references like the VisiBroker ORB or the POA cannot be stringified. If an attempt is made to do so, a MARSHAL exception is raised with the minor code 4.
Obtaining object and interface names
The table below shows the methods provided by the Object class that you can use to obtain the interface and object names as well as the repository id associated with an object reference. The interface repository is discussed in “Using Interface Repositories”.
Note
When you invoke bind() without specifying an object name, invoking the _object_name() method with the resulting object reference returns null .
Determining the type of an object reference
You can check whether an object reference is of a particular type by using the _is_a() method. You must first obtain the repository id of the type you wish to check using the _repository_id() method. This method returns true if the object is either an instance of the type represented by _repository_id() or if it is a sub-type. The member function returns false if the object is not of the type specified. Note that this may require remote invocation to determine the type.
You cannot use the instanceof keyword to determine the runtime type.
You can use _is_equivalent() to check if two object references refer to the same object implementation. This method returns true if the object references are equivalent. It returns false if the object references are distinct, but it does not necessarily indicate that the object references are two distinct objects. This is a lightweight method and does not involve actual communication with the server object.
Returns true if two objects refer to the same interface implementation.
Determining the location and state of bound objects
Given a valid object reference, your client program can use _is_bound() to determine if the object bound. The method returns true if the object is bound and returns false if the object is not bound.
The _is_local() method returns true if the client program and the object implementation reside within the same process or address space where the method is invoked.
The _is_remote() method returns true if the client program and the object implementation reside in different processes, which may or may not be located on the same host.
Narrowing object references
The process of converting an object reference's type from a general super-type to a more specific sub-type is called narrowing.
You cannot use the Java casting facilities for narrowing.
VisiBroker maintains a type graph for each object interface so that narrowing can be accomplished by using the object's narrow() method.
The IDL exception CORBA::BAD_PARAM is thrown if the narrow fails, because the object reference does not support the requested type.
public abstract class AccountManagerHelper {
...
public static Bank.AccountManager
narrow(org.omg.CORBA.Object object) {
...
}
...
}
Widening object references
Converting an object reference's type to a super-type is called widening. The code sample below shows an example of widening an Account pointer to an Object pointer. The pointer acct can be cast as an Object pointer because the Account class inherits from the Object class.
...
Account account;
org.omg.CORBA.Object obj;
account = AccountHelper.bind();
obj = (org.omg.CORBA.Object) account;
...
Using Quality of Service (QoS)
Quality of Service (QoS) uses policies to define and manage the connection between your client applications and the servers to which they connect.
Understanding Quality of Service (QoS)
QoS policy management is performed through operations accessible in the following contexts:
The VisiBroker ORB level policies are handled by a locality constrained PolicyManager, through which you can set Policies and view the current Policy overrides. Policies set at the VisiBroker ORB level override system defaults.
Thread level policies are set through PolicyCurrent, which contains operations for viewing and setting Policy overrides at the thread level. Policies set at the thread level override system defaults and values set at the VisiBroker ORB level.
Note
The QoS policies installed at the ORB level will only affect those objects on which no method is called before installing the policies, for example a non_existent call internally makes a call on a server object. If ORB level QoS policies are installed after the non_existent call, then the policies do not apply.
Policy overrides and effective policies
The effective policy is the policy that would be applied to a request after all applicable policy overrides have been applied. The effective policy is determined by comparing the Policy as specified by the IOR with the effective override. The effective Policy is the intersection of the values allowed by the effective override and the IOR-specified Policy. If the intersection is empty a org.omg.CORBA.INV_POLICY exception is raised.
QoS interfaces
The following interfaces are used to get and set QoS policies.
org.omg.CORBA.Object
Contains the following methods used to get the effective policy and get or set the policy override.
_get_policy returns the effective policy for an object reference.
_set_policy_override returns a new object reference with the requested list of Policy overrides at the object level.
com.inprise.vbroker.CORBA.Object
In order to use this interface, you must cast org.omg.CORBA.Object to com.inprise.vbroker.CORBA.Object. Because this interface is derived from org.omg.CORBA.Object, the following methods are available in addition to the ones defined in org.omg.CORBA.Object.
_get_client_policy returns the effective Policy for the object reference without doing the intersection with the server-side policies. The effective override is obtained by checking the specified overrides in first the object level, then at the thread level, and finally at the VisiBroker ORB level. If no overrides are specified for the requested PolicyType the system default value for PolicyType is used.
_get_policy_overrides returns a list of Policy overrides of the specified policy types set at the object level. If the specified sequence is empty, all overrides at the object level will be returned. If no PolicyTypes are overridden at the object level, an empty sequence is returned.
_validate_connection returns a boolean value based on whether the current effective policies for the object will allow an invocation to be made. If the object reference is not bound, a binding will occur. If the object reference is already bound, but current policy overrides have changed, or the binding is no longer valid, a rebind will be attempted, regardless of the setting of the RebindPolicy overrides. A false return value occurs if the current effective policies would raise an INV_POLICY exception. If the current effective policies are incompatible, a sequence of type PolicyList is returned listing the incompatible policies.
org.omg.CORBA.PolicyManager
The PolicyManager is an interface that provides methods for getting and setting Policy overrides for the VisiBroker ORB level.
get_policy_overrides returns a PolicyList sequence of all the overridden policies for the requested PolicyTypes. If the specified sequence is empty, all Policy overrides at the current context level will be returned. If none of the requested PolicyTypes are overridden at the target PolicyManager, an empty sequence is returned.
set_policy_overrides modifies the current set of overrides with the requested list of Policy overrides. The first input parameter, policies, is a sequence of references to Policy objects. The second parameter, set_add, of type org.omg.CORBA.SetOverrideType indicates whether these policies should be added onto any other overrides that already exist in the PolicyManager using ADD_OVERRIDE, or they should be added to a PolicyManager that doesn't contain any overrides using SET_OVERRIDES. Calling set_policy_overrides with an empty sequence of policies and a SET_OVERRIDES mode removes all overrides from a PolicyManager. Should you attempt to override policies that do not apply to your client, org.omg.CORBA.NO_PERMISSION will be raised. If the request would cause the specified PolicyManager to be in an inconsistent state, no policies are changed or added, and an InvalidPolicies exception is raised.
org.omg.CORBA.PolicyCurrent
The PolicyCurrent interface derives from PolicyManager without adding new methods. It provides access to the policies overridden at the thread level. A reference to a thread's PolicyCurrent is obtained by invoking org.omg.CORBA.ORB.resolve_initial_references and specifying an identifier of PolicyCurrent.
com.inprise.vbroker.QoSExt.DeferBindPolicy
The DeferBindPolicy determines if the VisiBroker ORB will attempt to contact the remote object when it is first created, or to delay this contact until the first invocation is made. The values of DeferBindPolicy are true and false. If DeferBindPolicy is set to true all binds will be deferred until the first invocation of a binding instance. The default value is false.
If you create a client object, and DeferBindPolicy is set to true, you may delay the server startup until the first invocation. This option existed before as an option to the Bind method on the generated helper classes.
The code sample below illustrates an example for creating a DeferBindPolicy and setting the policy on the VisiBroker ORB.
// Initialize the flag and the references
boolean deferMode = true;
Any policyValue= orb.create_any();
policyValue.insert_boolean(deferMode);

Policy policies =
orb.create_policy(DEFER_BIND_POLICY_TYPE.value, policyValue);

// Get a reference to the thread manager
PolicyManager orbManager =
PolicyManagerHelper.narrow(
orb.resolve_initial_references("ORBPolicyManager"));

// Set the policy on the ORB level
orbManager.set_policy_overrides(new Policy[] {policies},
SetOverrideType.SET_OVERRIDE);

// Get the binding method
byte[] managerId = "BankManager".getBytes();
Bank.AccountManager manager =
Bank.AccountManagerHelper.bind(orb, "/qos_poa", managerId);
com.inprise.vbroker.QoSExt.
ExclusiveConnectionPolicy
The ExclusiveConnectionPolicy is a VisiBroker-specific policy that gives you the ability to establish an exclusive (non-shared) connection to the specified server object. You assign this policy a boolean value of true or false. If the policy is true, connections to the server object are exclusive. If the policy is false, existing connections are reused if possible and a new connection is opened only if reuse is not possible. The default value is false.
This policy provides the same capabilities as were provided by Object._clone() in VisiBroker 3.x.
An example of how to establish exclusive and non-exclusive connections is provided in the CloneClient.java example which can be found in:
<install_dir>\examples\vbroker\QoS_policies\qos\
com.inprise.vbroker.QoSExt.RelativeConnectionTimeoutPolicy
The RelativeConnectionTimeoutPolicy indicates a timeout after which attempts to connect to an object using one of the available endpoints is aborted. The timeout situation could happen in various circumstances, for example with objects protected by firewalls, where HTTP tunneling is the only way to connect to the object.
The following code examples illustrates how to create RelativeConnectionTimeoutPolicy:
Any connTimeoutPolicyValue = orb.create_any();
// Input is in 100s of Nanoseconds.
// To specify a value of 20 seconds, use 20 * 10^7 nanoseconds as input

int connTimeout = 20;

connTimeoutPolicyValue.insert_ulonglong(connTimeout * 10000000);
org.omg.CORBA.Policy ctoPolicy =
orb.create_policyRELATIVE_CONN_TIMEOUT_POLICY_TYPE.value,
connTimeoutPolicyValue);
PolicyManager orbManager = PolicyManagerHelper.narrow (
orb.resolve_initial_references("ORBPolicyManager"));

orbManager.set_policy_overrides(new Policy[] \{ctoPolicy\},
SetOverrideType.SET_OVERRIDE);
org.omg.Messaging.RebindPolicy
RebindPolicy is used to indicate whether the ORB may transparently rebind once successfully bound to a target. An object reference is considered bound once it is in a state where a LocateRequest message would result in a LocateReply message with status OBJECT_HERE. RebindPolicy accepts values of type org.omg.Messaging.RebindMode and are set only on the client side. It can have one of six values that determine the behavior in the case of a disconnection, an object forwarding request, or an object failure after an object reference is bound. The supported values are:
org.omg.Messaging.TRANSPARENT allows the VisiBroker ORB to silently handle object-forwarding and necessary reconnections during the course of making a remote request. The code sample below illustrates an example to create a RebindPolicy of type TRANSPARENT and sets the policy on the VisiBroker ORB, thread, and object levels.
org.omg.Messaging.NO_REBIND allows the VisiBroker ORB to silently handle reopening of closed connections while making a remote request, but prevents any transparent object-forwarding that would cause a change in client-visible effective QoS policies. When RebindMode is set to NO_REBIND, only explicit rebind is allowed.
org.omg.Messaging.NO_RECONNECT prevents the VisiBroker ORB from silently handling object-forwards or the reopening of closed connections. You must explicitly rebind and reconnect when RebindMode is set to NO_RECONNECT.
com.inprise.vbroker.QoSExt.VB_TRANSPARENT is the default policy. It extends the functionality of TRANSPARENT by allowing transparent rebinding with both implicit and explicit binding. VB_TRANSPARENT is designed to be compatible with the object failover implementation in VisiBroker 3.x.
com.inprise.vbroker.QoSExt.VB_NOTIFY_REBIND throws an exception if a rebind is necessary. The client catches this exception, and binds on the second invocation. If a client has received a CloseConnection message before, it will also reestablish the closed connection.
com.inprise.vbroker.QoSExt.VB_NO_REBIND does not enable failover. It only allows the client VisiBroker ORB to reopen a closed connection to the same server; it does not allow object forwarding of any kind.
Note
Be aware that if the effective policy for your client is VB_TRANSPARENT and your client is working with servers that hold state data, VB_TRANSPARENT could connect the client to a new server without the client being aware of the change of server, and in that case any state data held by the original server will be lost.
Note
If the Client has set RebindPolicy and the RebindMode is anything other that the default(VB_TRANSPARENT), then the RebindPolicy is propagated in a special ServiceContext as per the CORBA specification. The propagation of the ServiceContext occurs only when the client invokes the server through a GateKeeper or a RequestAgent. This propagation does not occur in a normal Client/Server scenario.
The following table describes the behavior of the different RebindMode types.
The appropriate CORBA exception will be thrown in the case of a communication problem or an object failure.
The following example creates a RebindPolicy of type TRANSPARENT and sets the policy on the VisiBroker ORB, thread, and object levels.
Any policyValue= orb.create_any();
RebindModeHelper.insert(policyValue,
org.omg.Messaging.TRANSPARENT.value);
Policy myRebindPolicy = orb.create_policy(REBIND_POLICY_TYPE.value,
policyValue);
//get a reference to the ORB policy manager
org.omg.CORBA.PolicyManager manager;
try {
manager = PolicyManagerHelper.narrow(orb.resolve_initial_references("ORBPolicyManager"));
}
catch(org.omg.CORBA.ORBPackage.InvalidName e) {}
//get a reference to the per-thread manager
org.omg.CORBA.PolicyManager current;
try {
current =
PolicyManagerHelper.narrow(orb.resolve_initial_references
("PolicyCurrent"));
}
catch(org.omg.CORBA.ORBPackage.InvalidName e) {}
//set the policy on the orb level
try{
manager.set_policy_overrides(myRebindPolicy,
SetOverrideType.SET_OVERRIDE);
}
catch (InvalidPolicies e){}
// set the policy on the Thread level
try {
current.set_policy_overrides(myRebindPolicy,
SetOverrideType.SET_OVERRIDE);
}
catch (InvalidPolicies e){}
//set the policy on the object level:
org.omg.CORBA.Object oldObjectReference=bind(...);
org.omg.CORBA.Object newObjectReference=oldObjectReference._set_policy_override
(myRebindPolicy, SetOverrideType.SET_OVERRIDE);
For more information on QoS policies and types, see the Messaging section of the CORBA specification.
org.omg.CORBA.Messaging.RelativeRequestTimeout
Policy
The RelativeRequestTimeoutPolicy indicates the relative amount of time which a Request or its responding Reply may be delivered. After this amount of time, the Request is canceled. This policy applies to both synchronous and asynchronous invocations. Assuming the request completes within the specified timeout, the Reply will never be discarded due to timeout. The timeout value is specified in hundreds of nanoseconds. This policy is only effective on established connections, and is not applicable to establishing a connection.
The following code illustrates how to create RelativeRequestTimeoutPolicy:
// Specify the request timeout in 100s of Nanosecs.
// To set a timeout of 20 secs, set 20 * 10^7
int reqTimeout = 20;
Any policyValue = orb.create_any();
policyValue.insert_ulonglong(reqTimeout * 10000000);
// Create Policy
org.omg.CORBA.Policy reqPolicy = orb.create_policy(
RELATIVE_REQ_TIMEOUT_POLICY_TYPE.value, policyValue);
PolicyManager orbManager = PolicyManagerHelper.narrow(
orb.resolve_initial_references("ORBPolicyManager"));
orbManager.set_policy_overrides(new Policy[] {reqPolicy},
SetOverrideType.SET_OVERRIDE);
org.omg.CORBA.Messaging.RelativeRoundTripTimeout
Policy
The RelativeRoundTripTimeoutPolicy specifies the relative amount of time for which a Request or its corresponding Reply may be delivered. If a response has not yet been delivered after this amount of time, the Request is canceled. Also, if a Request had already been delivered and a Reply is returned from the target, the Reply is discarded after this amount of time. This policy applies to both synchronous and asynchronous invocations. Assuming the request completes within the specified timeout, the Reply will never be discarded due to timeout. The timeout value is specified in hundreds of nanoseconds.
This policy is also effective in the initial establishment of a connection.
The following code illustrates how to create RelativeRoundTripTimeoutPolicy:
// Specify the round-trip timeout in 100s of Nanoseconds
// To set a timeout of 50 secs, set 50 * 10^7
int rttTimeout = 50;
Any policyValue = orb.create_any();
policyValue.insert_ulonglong(rttTimeout * 10000000);
//Create the RelativeRoundTripTimeoutPolicy and set it at ORB level
org.omg.CORBA.Policy rttPolicy = orb.create_policy(
RELATIVE_RT_TIMEOUT_POLICY_TYPE.value, policyValue);
PolicyManager orbManager = PolicyManagerHelper.narrow(
orb.resolve_initial_references("ORBPolicyManager"));
orbManager.set_policy_overrides(new Policy[] {rttPolicy},
SetOverrideType.SET_OVERRIDE);
org.omg.CORBA.Messaging.SyncScopePolicy
The SyncScopePolicy defines the level of synchronization for a request with respect to the target. Values of type SyncScope are used in conjunction with a SyncScopePolicy to control the behavior of one-way operations.
The default SyncScopePolicy is SYNC_WITH_TRANSPORT. To perform one-way operations via the OAD, you must use SyncScopePolicy=SYNC_WITH_SERVER. Valid values for SyncScopePolicy are defined by the OMG.
Note
Applications must explicitly set an VisiBroker ORB-level SyncScopePolicy to ensure portability across VisiBroker ORB implementations. When instances of SyncScopePolicy are created, a value of type Messaging::SyncScope is passed to CORBA::ORB::create_policy. This policy is only applicable as a client-side override.
Exceptions
Raised when the RebindPolicy has a value of NO_REBIND, NO_RECONNECT, or VB_NO_REBIND and an invocation on a bound object references results in an object-forward or location-forward message.
Raised when the requested Policy is not supported.
Raised when an operation is passed a PolicyList sequence. The exception body contains the policies from the sequence that are not valid, either because the policies are already overridden within the current scope, or are not valid in conjunction with other requested policies.
Code Set support
VisiBroker supports Code Set Negotiation that allows applications to agree on a common Code Set when marshaling char or wchar IDL data types. A Code Set is a collection of unambiguous rules that establishes a character set and the one-to-one relationship between each character of the set and its bit representation or numeric value.
Types of Code Sets
Code sets can differ in their classification. Some language environments distinguish between byte-oriented and “wide characters”. The byte-oriented characters are encoded in one or more 8-bit bytes. ASCII (as used for western European languages like English) is an example of a typical single-byte encoding. A typical multi-byte encoding which uses from one to three 8-bit bytes for each character is eucJP (Extended UNIX Code—Japan, packed format), used for Japanese workstations. Although byte-oriented Code Sets such as UTF-8 uses one to six 8-bit bytes for a character representation, the CORBA specification mandates that for char data the size limit is still one byte and that char[] should be used if a representation uses more than one byte.
Wide characters are a fixed 16 or 32 bits long, and are used for languages like Chinese and Japanese, where the number of combinations offered by 8 bits is insufficient and a fixed-width encoding is needed. A typical example is Unicode (a “universal” character set defined by The Unicode Consortium). An extended encoding scheme for Unicode characters is UTF-16 (UCS Transformation Format, 16-bit representations).
Native Code Set
A native code set is the code set which a client or a server uses to communicate with its ORB. There might be separate native code sets for char and wchar data.
Conversion Code Set (CCS)
This is the set of target code sets for which an ORB can convert all encodings between the native code set and that target code set. For each code set in this CCS, the ORB maintains appropriate translation or conversion procedures and advertises the ability to use that code set for transmitted data in addition to the native code set.
Transmission Code Set (TCS)
A transmission code set is the commonly agreed upon encoding used for character data transfer between a client's ORB and a server's ORB. There are two transmission code sets established per session between a client and its server, one for char data (TCS-C) and the other for wchar data (TCS-W).
Code Set Negotiation
The client-side ORB determines a server's native and conversion code sets from an IOR multi-component profile structure, simultaneously determining a client's native and conversion code sets. From this information, the client-side ORB chooses char and wchar transmission code sets (TCS-C and TCS-W). For both requests and replies, the char TCS-C determines the encoding of char and string data, and the wchar TCS-W determines the encoding of wchar and wstring data.
Supported Code Sets
VisiBroker supports the following code sets:
For IDL char data types the native Code Set is ISO 8859-1 (Latin-1) and the conversion Code supported is UTF-8.
For IDL wchar data types the native Code Set is UTF-16 and there is no Conversion Code Set.
Deploying client-only applications using Client Run-time
In many application deployments you need only a client run-time rather than a full-sized ORB implementation. If the application is a pure client and has no server-side functionality, such as POA creation and object activation, VisiBroker provides a client run-time library for such scenarios. The VisiBroker Client Run-time has a smaller memory footprint compared to the full VisiBroker implementation. The client run-time is provided as a Java archive (vbjclientorb.jar) file which is installed under the /lib directory in the VisiBroker installation.
Note
The Client Run-time does not support full ORB functionality.
The following features are supported by the VisiBroker client run-time library:
The following features are not supported by the VisiBroker client runtime library:
Usage
To make use of vbjclientorb.jar, modify <install_dir>/bin/vbj.config to configure an addpath entry for vbjclientorb.jar. To make this change, replace the following line in the vbj.config file:
addpath $var(defaultJarPath)/vbjorb.jar
with:
addpath $var(defaultJarPath)/vbjclientorb.jar
When using VisiSecure in client applications, vbsec.jar, sunjce_provider.jar, local_policy.jar, US_export_policy.jar should also be present in the classpath. If JDK 1.3.1 is used, the JAR files jsse.jar, jcert.jar, jnet.jar, jaas.jar, and jce1_2_1.jar should also be present in the classpath, in addition to the JARs mentioned previously.
Note
If a particular feature is not supported by the client runtime (vbjclientorb.jar), at runtime the following standard error message is printed out along with the ClassNotFound or NoClassDefFound exception:
******Client runtime does not support full ORB functionality ******