To write and test code for your ActiveX client, you must be connected to a server (or have the server running on your machine) and have the ActiveX runtime files installed on your machine. To install the ActiveX runtime files, see “Deploy the ActiveX client”; if you install EAServer on your machine, you have the option to install the ActiveX runtime files as well. For more information, see the EAServer Installation Guide.
Before invoking methods on component instances, the client must connect to a server and instantiate the components. There are two techniques for proxy instantiation:
Instantiating proxies using CORBA-style interfaces – This technique follows the CORBA client model. This technique is recommended for new development.
Instantiating stub instances using the EAServer 1.1 interface – This technique uses interfaces that introduced in EAServer version 1.1. These interfaces are provided for backward compatibility with existing clients.
If you currently have ActiveX proxy automation server clients, Sybase recommends that you migrate you current ActiveX clients to use the CORBA-style so that you can take advantage of the new benefits. The following features are available to CORBA style clients and not to EAServer 1.1 style clients:
Use the ORB, Session, Factory, and Manager objects and methods.
Configure ORB level properties.
Use high availability/load balancing features.
Use most SSL features.
Invoke Enterprise JavaBean components.
The ORB, SessionManager, and other CORBA-style interfaces are documented in Chapter 4, “ActiveX Client Interfaces,” in the EAServer API Reference.
Proxies are local objects that allow you to call EAServer component methods as if the component were a local object in your program. Instantiate proxies using the EAServer ORB and SessionManager::Manager interfaces, as follows:
Step |
What it does |
Detailed explanation |
---|---|---|
1 |
Initialize the CORBA ORB and create an ORB reference. |
|
2 |
Use the ORB reference to create a Manager instance for the server. |
|
3 |
Use the Manager instance to create a Session. |
|
4 |
Use the Session instance to create stub component instances. |
|
5 |
Call the stub methods to remotely invoke component methods. |
If you are using Visual Basic, before using the ORB,
Session, Factory, and Manager objects in your client, create references
to JaguarORB.tlb, SessionManager.tlb and CtsSecurity.tlb in
your Visual Basic project using the standard Visual Basic mechanism.
Before any ORB classes can be used, you must call the init method, which:
Returns an object reference to the ORB.
Allows you to pass initialization parameters to control the operation of the ORB. For example, you can specify the password for access to the Sybase SSL certificate database.
The ORB.init() method acceps a formatted
string that can contain settings for multiple initialization parameters.
Pass initialization parameters as shown in this example, which configures
the -ORBlogFile
property and
the -ORBpin
property, to specify
a file name for logging errors and the Sybase SSL-certificate-database
password, respectively:
orb.init("-ORBlogFile=d:\jagorb.log,-ORBpin=sybase")
As shown in the example, parameter names and values must be separated by an equals sign, ‘=’, and each name/value pair must be separated from the next with a comma and no white space.
For each initialization parameter, there is an equivalent environment variable. If the environment variable and initialization parameter are set, the value of the initialization parameter is used. Parameter and environment variable names are the same as for the C++ client ORB (see Chapter 15, “Creating CORBA C++ Clients”).
You can set any initialization parameter to a value of none, which overrides the value of the environment variable and sets the value to the default, if any.
You can pass the following initialization parameters to the driver class:
ORBNameServiceURL – This parameter sets the IIOP URL to the EAServer name service. This parameter can also be set in an environment variable, JAG_NAMESERVICEURL. This parameter is used in conjunction with the EAServer name service and is specified according to the following syntax:
iiop://hostname:iiop-port/initial-context
where:
hostname is the host machine name for the server that serves as the name server for your client. If omitted, the default host name applies.
iiop-port is the IIOP port number for the server.
initial-context is the initial naming
context, which you set in the server property Initial Context. This
can be used to set a default prefix for name resolution. For example,
if you specify USA/Sybase/
,
all names that you resolve with the context are assumed to be relative
to this location in the name hierarchy. When specifying the initial
context, a trailing slash is optional; it is added automatically
if you do not specify an initial context that ends with a slash.
If your application uses a cluster of servers, the cluster may use multiple name servers. In this case, specify the URL (host machine name and IIOP port number) for each name server in a list separated by semicolons and no white space. Include the cluster’s initial naming context only with the last URL. For example:
iiop://host1:9000;iiop://host2:9000/USA/Sybase/
ORBHttp – This specifies whether the ORB should use HTTP-tunnelling to connect to the server. A setting of "true" specifies HTTP tunnelling. The default is "false". This parameter can also be set in an environment variable, JAG_HTTP. Some firewalls may not allow IIOP packets through, but most all allow HTTP packets through. When connecting through such firewalls, set this property to "true".
ORBLogIIOP – This specifies whether the ORB should log IIOP protocol trace information. A setting of "true" enables logging. The default is "false". This parameter can also be set in an environment variable, JAG_LOGIIOP. When this parameter is enabled, you must set the ORBLogFile option (or the corresponding environment variable) to specify the file where protocol log information is written.
ORBLogFile – This sets the path and name of the file to which to log client execution status and error messages. This parameter can also be set in an environment variable, JAG_LOGFILE. The default setting is no log.
ORBCodeSet – This sets the code set that the client uses. This parameter can also be set in an environment variable, JAG_CODESET. The default setting is iso_1.
ORBRetryCount – Specify the number of times to retry when the initial attempt to connect to the server fails. This parameter can also be set in an environment variable, JAG_RETRYCOUNT. The default is 5.
ORBRetryDelay – Specify the delay, in milliseconds, between retry attempts when the initial attempt to connect to the server fails.This parameter can also be set in an environment variable, JAG_RETRYDELAY. The default is 2000.
ORBProxyHost – Specifies the machine name or the IP address of an SSL proxy. See Chapter 12, “Deploying Applications Around Proxies and Firewalls,” in the EAServer Security Administration and Programming Guide for more information.
ORBProxyPort – Specifies the port number of the SSL proxy.
ORBsocketReuseLimit – Specifies the number of times that a network connection may be reused to call methods from one server. The default is 0, which indicates no limit. The default is ideal for short-lived clients. The default may not be appropriate for a long-running client program that calls many methods from servers in a cluster. If sockets are reused indefinitely, the client may build an affinity for servers that it has already connected to rather than randomly distributing its server-side processing load among all the servers in the cluster. In these cases, the property should be tuned to best balance client performance against cluster load distribution. In Sybase testing, a setting of 10 to 30 proved to be a good starting point. If the reuse limit is too low, client performance degrades.
ORBIdleConnectionTimeout – Specifies the time, in seconds, that a connection is allowed to sit idle. When the timeout expires, the ORB closes the connection. The default is 0, which specifies that connections can never timeout. The connection timeout does not affect the life of proxy instance references; the ORB may close and reopen connections transparently between proxy method calls. Specifying a finite timeout for your client applications can improve server performance. If many instances of the client run simultaneously, a finite client connection timeout limits the number of server connections that are devoted to idle clients. A finite timeout also allows rebalancing of server load in an application that uses a cluster of servers.
ORB initialization is demonstrated in the following example.
Dim orb As ORB Dim Manager As Manager Dim Session As Session Dim Factory As Factory ' Create a new ORB object Set orb = New ORB ' Initialize the ORB instance orb.init ("")
init returns an object reference to the EAServer ORB. When orb is deallocated or assigned a new object reference, it will be automatically released.
The SessionManager::Manager interface is used for interacting with a server. To create a Manager instance, you must identify a server listener using a URL of the format:
protocol://host:port
where:
protocol is iiop
or iiops
.
Use iiops
for connections to
secure iiop
listeners.
host is the server’s host machine name or IP address.
port is the listener’s port number.
Pass the URL to the string_to_object method to convert the URL string into a Manager instance, as shown in the following example. The object returned by string_to_object must be narrowed to the SessionManager/Manager interface.
Dim orb As ORB Dim Manager As Manager Dim obj as Object ... deleted orb initialization ... Set obj = orb.string_to_object( "iiop://puddle:9000") Set Manager = obj.Narrow_("SessionManager/Manager") ...
The SessionManager::Session interface represents an authenticated session between the client application and a server. The createSession method accepts a user name and password and returns a session object, as shown in the example below:
Dim orb As ORB Dim Manager As Manager Dim Session as Session Dim obj as Object ...deleted manager initialization Set obj = Manager.createSession("jagadmin","") Set Session = obj.Narrow_("SessionManager/Session") ...
You call the Session.lookup method to return an object reference factory. You then use the factory to create one or more proxies for the component.
lookup takes a string that specifies the
EAServer component name. By default, the name is package/component,
where package is the EAServer Manager package
name and component is the component name. Package
and component names are not case sensitive. Component developers
can override the default name by setting the JNDI Name property
for EJB components, or the com.sybase.jaguar.component.bind.naming
property
for other types of components.
lookup returns a CORBA::Object reference. You use Narrow_ to convert the object reference into an instance of the factory for the component.
After instantiating the factory, the factory Create method returns an instance of the component proxy.
The code to instantiate a proxy for a component named Foo/Bar looks like this:
Dim Session as Session Dim fact as Factory Dim barComp as Bar // Component proxy Dim obj as Object ...deleted session initialization ... Set obj = Session.lookup("Foo/Bar") Set fact = obj.Narrow_("SessionManager/Factory") Set barComp = fact.Create()
Sybase recommends that you use the CORBA style interfaces for new development. The EAServer 1.1 interface is provided for backward compatibility with existing applications.
To invoke EAServer components, your ActiveX client should:
Declare proxy objects – The application creates an ActiveX interface pointer for the proxy object.
Set connection properties – The application sets connection properties for the component instance. These properties describe the server that contains the component and the user name to be used for a connection.
Instantiate server components – The application calls the proxy object’s Initialize method. Initialize connects to the server and creates an instance of the server component. After Initialize succeeds, the server component methods can be called through the proxy object.
Invoke component methods – The application invokes methods on the server, passing the appropriate ActiveX datatype for each parameter.
Proxy objects are instantiated and invoked via ActiveX dispatch interfaces. EAServer proxy objects can be identified by their program identifier (ProgID). See “Check the ProgID for each interface” for more information.
Different ActiveX-enabled IDEs have different mechanisms for declaring an ActiveX object. In Visual Basic, you can simply declare the proxy object and instantiate it. For example, you can write either one of the following to instantiate a proxy object:
Dim bar as Bar Set bar = New Bar
or
Dim bar as Object Set bar = CreateObject(“Foo.Bar”)
Although the ActiveX proxy object exists once you have declared it, you cannot invoke methods until after you have set connection properties and called the Initialize method.
Before
calling the Initialize method, set the connection
properties, such as UserName
, Password
, Host
,
and Name
. The ActiveX client
uses connection properties to connect to the server. This example
sets the connection information for the employeeproxy
object.
employeeproxy.UserName = "Guest" employeeproxy.Password = "Guest" employeeproxy.Host = "Jaguar" employeeproxy.Name = "Company/Employee"
The user name and password, which must be specified, are required for login authentication and access control. The defaults for user name and password are empty strings. If the server administrator has enabled authentication, you must use a valid user name and password. If user access to the package or component is limited, the user name must be in a group that has access to the component. For more information on security, see Chapter 2, “Securing Component Access,” in the EAServer Security Administration and Programming Guide.
The Host
property,
which is optional, is the machine name and IIOP port number or the
environment variable that specifies the machine name and IIOP port
number. If the machine name and IIOP port number are specified for
the Host
property, the
environment variable is ignored. See “Deploy the ActiveX client” for more information about defining
the environment variable.
The syntax for specifying the machine name and IIOP port number is:
"machine:port"
where:
machine is the machine name.
port is the IIOP port number.
If the
Host
property
or environment variable is not specified, or defined incorrectly,
the default, which is “localhost:9000”, is used.
The Name
property,
which is optional, specifies the package and component names. By
default, the package name is the same as the module name, and the component
name is the same as the interface name. Specify the Name
property when
a component’s package or component name is different from
its module or interface name. The package and component are automatically
located relative to the server’s Initial
Context
property. The syntax for the Name
property
is:
"package/component"
where:
package is the name of the package.
component is the name of the component.
If the
Name
property
is not specified, or defined incorrectly, the default is used.
To instantiate the components on the server, use the Initialize() method. Initialize() establishes
a connection to the server, using the connection properties you
set in the previous step. If the server host name is not valid,
or if another error occurs, the APAS displays an error message.
This example executes the Initialize() method
on the employeeproxy
object,
and instantiates on the server an instance of the Employee component
belonging to the Company package.
employeeproxy.Initialize()
“ActiveX datatype support” lists the ActiveX types supported by EAServer, as well as the equivalent EAServer Manager and CORBA IDL types.
EAServer components appear as automation objects in the ActiveX-enabled IDE. If your IDE supports it, you can simply drag and drop the component method into your ActiveX client code and use the IDE’s object browser to see the component’s method syntax. You must call the proxy methods using the syntax required by your development tool.
To execute a component method, execute the method on the proxy
object. In this example, the GetEmployeeInfo() and
the SetEmployeeInfo() methods are executed on employeeproxy
.
The parameters in the SetEmployeeInfo() method
are in parameters. The parameters in the GetEmployeeInfo() method
are inout parameters.
String name Long age String sex name = "John" age = 32 sex = "male" // Example for parameters using the in argument mode employeeproxy.SetEmployeeInfo (name, age, sex) // Example for parameters using the inout argument mode employeeproxy.GetEmployeeInfo (REF name, REF age, REF sex)
Methods may return result sets. After a method invocation, you can retrieve result sets as described in “Result-set support”.
If a component that the ActiveX client accesses is an
ActiveX component and a C++ IDE such as Visual
C++ was used to develop it, string parameter types
are always passed by reference (as BSTR *). Make sure that
you defined these parameters as inout in EAServer
Manager.
When you invoke component methods, these restrictions apply:
You must pass parameters in a datatype that is equivalent to the corresponding parameter’s datatype in the EAServer method definition. See “ActiveX datatype support” for more information.
You must pass parameters by position; named arguments to method calls are not supported.
You cannot use methods with names that differ only in case.
The result-set parameter type is not allowed in either in or inout modes.
Always make sure that your application handles exceptions gracefully. At minimum, you should display the exception text, which will aid debugging.
Errors in ActiveX proxy execution can be handled as ActiveX exceptions, or inline using a try/catch model similar to the structured exception handling model in the C++ and Java languages.
By default, the ActiveX proxy raises an ActiveX exception when an EAServer component method raises an exception or an internal error occurs. Visual Basic and most other ActiveX scripting tools do not allow you to handle these errors inline. Instead, control transfers to an error handler (specified by on error goto in Visual Basic) or to a system-wide error dialog box. To handle proxy errors inline, you must enable inline exception handling as described in “Handling exceptions inline”.
In C++, the OLE EXCEPINFO structure describes an ActiveX exception. Different ActiveX-enabled IDEs provide different mechanisms for applications to obtain the EXCEPINFO structure contents.
In Visual Basic, exceptions are mapped to the built-in Err object. The exception number maps to Err.Number and the description is available as Err.Description. You can handle exceptions by activating error handling code with On Error Goto statement or by checking whether Err.Number is > 0.
The proxy type library defines error numbers for client-side errors in the JagORBClientErrNum enumeration and server-side error numbers in the JagORBServerErrNum enumeration.
IDL user-defined exceptions are not supported and are
mapped to error number 9000.
Table 20-1 lists the codes for client-side error numbers defined in the JagORBClientErrNum enumeration:
Table 20-2 lists the codes for server-side error numbers defined in the JagORBServerErrNum enumeration:
By default, the ActiveX proxy raises an ActiveX exception when an EAServer component method raises an exception or an internal error occurs. Visual Basic and most other ActiveX scripting tools do not allow you to handle these errors inline. Instead, control transfers to an error handler (specified by on error goto in Visual Basic) or to a system-wide error dialog box.
Inline exception handling can simplify the code that handles recoverable errors. For example, you can keep program logic that allows a user to retry a failed login in one place, rather than split into mainline code and the separate error handling code. Inline exception handling also allows you to handle errors explicitly in scripting tools that do not allow you to install user-coded error handlers.
The ActiveX proxy supports inline exception handling with Try, Catch, and End methods and an internal exception store. When an exception occurs with inline handling active, the proxy stores the error information rather than raising an ActiveX exception. Each component proxy object supports these methods and contains an exception store that is specific to that object. To handle exceptions inline, call the Try_, Catch_, and End_ methods as follows:
Try_ Activates inline exception handling. Errors or exceptions that occur after calling Try and before End do not raise ActiveX exceptions. Instead, the error is stored in an internal exception store that can be accessed with the Catch method.
Catch_ Check whether an exception of a specified type has occurred. Catch has this syntax:
boolean Catch_( in string exceptionType, out Object exception )
Where exceptionType is the exception type to check for or “...” to check for the occurrence of any exception, and exception is an output variable. If the exception store contains an exception of the specified type, Catch_ copies the exception store to the exception variable, clears the exception store, and returns true.
You can call Catch_ multiple times to check for exceptions of different types.
End_ Deactivates inline exception handling and reverts to the standard ActiveX error handling mechanism. If the exception store contains an exception instance, End_ throws the stored exception as an ActiveX exception.
The Try_ and Catch_ methods do not have the same semantics of structured exception handling in Java or C++. In particular:
Since the exception store holds only one exception instance, you must call Try_ after every proxy method invocation that can raise an exception. Otherwise, an exception in the store can be overwritten by the most recently thrown exception.
If you return from a subroutine with inline exception handling active for an object, it remains active for that object.
Inline exception handling in multithreaded programs requires that you use a separate copy of a proxy object in each thread. See “Using Try_ and Catch_ in multithreaded programs” for more information.
When you call the Catch_ method, you can check for exceptions of a specific type, or for exceptions of any type. To check for any exception, pass “...” as the exception type parameter.
The following example illustrates this style of exception handling:
barcomp.Try_ barcomp.methodThatRaisesException(1007) Dim anyExcep As Object If (barcomp.Catch_("...", anyExcep) = True) Then Dim excepType as String excepType = anyExcep.GetExceptionType if (StrComp(excepType, "Foo/NotValidIdException") == 0) then Dim invalidIdExcep as NotValidIdException set invalidIdExcep = anyExcep Dim id as integer Dim msg as String id = invalidIdExcep.id msg = invalidIdExcep.message Else if (StrComp(excepType, "Foo/NoAuthorizationException") == 0) then Dim noAuthorizationExcep as NoAuthorizationException set noAuthorizationExcep = anyExcep Dim user as String Dim cert as String user = noAuthorizationExcep.username cert = noAuthorizationExcep.certificate Else if (StrComp(excepType, "Jaguar/ClientException") == 0) then Dim systemExcep as SystemException set systemExcep = excep Dim code as integer Dim msg as String code = systemExcep.code msg = systemExcep.message End if Else ' No Exception has occurred. Proceed End If
Exception datatypes are used with the Try_ method when handling exceptions inline. The ActiveX proxy includes predefined system exceptions that correspond to the standard CORBA system exceptions. User-defined exceptions that are declared in an IDL module are also mapped to ActiveX types.
System exceptions In IDL, system exceptions extend the CORBA SystemException IDL type:
interface SystemException { long code; // numeric error code string message; // text error message };
Unlike user-defined exceptions, a component method can throw system exceptions that are not listed in the raises clause of the IDL method signature. The C++ and ActiveX client runtime engines may also raise system exceptions when errors occur in the processing of a method invocation.
In the ActiveX proxy, system exceptions are mapped to the interface SystemException with the following properties and methods:
The Code property specifies the numeric error code.
The Message property specifies the text error description, if available.
The GetExceptionType method returns the string exception identifier (see “Exception identifiers” for more information).
The ActiveX proxy uses SystemException to represent the standard CORBA system exception types that can be returned by components, as well as errors that occur in the ActiveX proxy. “Exception identifiers” lists the system exception types.
User-defined exceptions In IDL, user-defined exceptions are defined using syntax similar to an IDL structure. For example:
exception InvalidValueException { string message; string value; };
User-defined exceptions can be defined within an IDL module or interface. The IDL method signature for a component method must list user-defined exceptions thrown by the method in the raises clause. A method cannot throw user-defined exceptions that are not listed in the raises clause.
In ActiveX, the IDL exception maps to an interface with the following properties and methods:
One get/set property for each member field in the exception, following the datatype mappings for IDL to ActiveX types.
A GetExceptionType method that returns the string exception identifier (see “Exception identifiers” for more information).
Exception identifiers Both system and user-defined exceptions support a GetExceptionType method that returns a string identifier for the exception. The exception identifier for a user-defined exception defined in a module is:
module/exception
Where module is the IDL module name and exception is the IDL exception type. For example, “CtsSecurity/No Certificate Exception”. The exception identifier for an exception defined in an interface is:
module/interface/exception
Where interface is the IDL interface name.
Exception identifiers for system exceptions are predefined, as listed in Table 20-3.
This example calls a method CtsSecurity.SSLServiceProvider.setGlobalProperty. This method can be called to specify SSL settings for a connection to a server. For more information, see Chapter 8, “Using SSL in ActiveX Clients,” in the EAServer Security Administration and Programming Guide.
The method signature and the exceptions raised are detailed in the following IDL:
module CtsSecurity { interface SSLServiceProvider { string setGlobalProperty ( in string property, in string value ) raises (CtsSecurity::InvalidPropertyException, CtsSecurity::InvalidValueException); }; exception InvalidPropertyException { string message; string property; }; exception InvalidValueException { string message; string value; }; };
setGlobalProperty raises InvalidValueException if you attempt to set a property to an invalid value, and raises InvalidPropertyException if you specify a property that does not exist.
The following Visual Basic code calls setGlobalProperty and calls the Catch method to handle InvalidValueException inline. Since there is no Catch_ call for InvalidPropertyException, if this exception is thrown, it will be thrown as an ActiveX exception when End_ is called:
Dim ssp as CtsSecurity.SSLServiceProvider // Assume ssp has been properly initialized Dim ivException as CtsSecurity.InvalidValueException // Activate inline exception handling call ssp.Try ssp.setGlobalProperty("qop", "An invalid value") if (ssp.Catch_("CtsSecurity/InvalidValueException", ivException) then call MessageBox ("Invalid value: " & ivException.value & ". " & _ ivException.message, , "Error"); endif call ssp.End_
If your program uses a proxy object in multiple threads and handles exceptions inline, you must call the Duplicate_ method to obtain a copy of the proxy object for use in each thread. Duplicate_ has the following syntax:
Object Duplicate_
Duplicate_ returns a proxy instance of the same type as the original.
Copyright © 2005. Sybase Inc. All rights reserved. |
![]() |