Chapter 9: EAServer EJB Interoperability
ActiveX clients can instantiate an EJB component using a proxy for the component’s home interface, then call business methods using a proxy for the component’s remote interface.
For a description of EAServer’s ActiveX client proxy, see Chapter 20, “Creating ActiveX Clients.”
ActiveX clients can call methods that are defined using only IDL datatypes. EAServer allows serializable Java classes to be used as parameters and return values. Methods that use Java classes as a parameter or return value cannot be called from ActiveX clients.
Most EJB home interfaces have overloaded methods, and many imported Java components use nested IDL modules.
The Java interfaces for an EJB component may have overloaded methods; that is, several methods with the same name that differ in the number and type of parameters. For example, a home interface may contain several create methods. EAServer maps such methods to uniquely named IDL methods by appending two underscores and a suffix to the Java method name. ActiveX does not support overloaded methods, so you must use the full IDL method names for methods that are overloaded in the Java interface.
For example, if a Java home interface has these methods:
mypackage.MyBeanRemote Create() mypackage.MyBeanRemote Create(String p1, long p2) mypackage.MyBeanRemote Create( String p1, String p2, long p3)
The IDL equivalent might be:
mypackage::MyBean Create() mypackage::MyBean Create__String(string p1, long p2) mypackage::MyBean Create__StringString( string p1, string p2, long p3)
To determine the full IDL method names, view the IDL interface in EAServer Manager.
EAServer supports nested IDL modules. IDL modules that define the interfaces for an EJB component typically follow the Java package structure of the component’s Java interfaces. For example, if the Java interfaces are in the Java package com.sybase.foo, IDL interfaces are in module com::sybase::foo. When implementing ActiveX clients, you must understand how nested IDL modules are mapped to ActiveX interface PROGIDs and the type names used in Object.Narrow_ calls.
The ActiveX PROGID for an IDL type defined in a nested IDL module follows this naming pattern:
Each nested module name is preceded by an underscore, and
the IDL type name is preceded by a period (.). For example, the
PROGID for IDL type com::sybase::foo::MyBeanRemote is
When specifying type names in Object.Narrow_ calls,
substitute a forward slash (/) for every double-colon (::)
in the IDL type name. For example, if the IDL type is com::sybase::foo::MyBeanRemote,
the call to Object.Narrow_.
An EJB home interface contains methods that return proxies for the component’s remote interface.
The home interface for an entity bean contains finder methods that can be used to obtain instances that represent rows already in the underlying database.
To instantiate a home interface, use a SessionManager::Manager instance to create a SessionManager::Session instance, then call the SessionManager::Session::lookup method, passing the bean’s home interface name. Narrow the returned object to the bean’s home interface.
The example below instantiates the home interface named bookStore/customerMaintenance. In IDL, the home interface is bookStore::custMaintenanceHome:
' Initialize the ORB Dim orbRef As JaguarTypeLibrary.ORB Set orbRef = New JaguarTypeLibrary.ORB orbRef.Init ("") ' Get a SessionManager::Manager proxy Dim manager_ior As String Dim CORBAObj As Object Dim sessManager As SessionManager.Manager manager_ior = Format("iiop://" & host & ":" & port) Set CORBAObj = _ orbRef.string_to_object(manager_ior) Set sessManager = CORBAObj.Narrow_("SessionManager/Manager") ' Get a Session proxy, passing username and password Dim session As SessionManager.session Set CORBAObj = sessManager.createSession( _ userName, password) Set session = CORBAObj.Narrow_("SessionManager/Session") ' Get a proxy for the home interface Dim home As bookStore.custMaintenanceHome Set CORBAObj = session.lookup("bookStore/custMaintenance") Set home = CORBAObj.Narrow_("bookStore/custMaintenanceHome")
Each instance of an entity bean represents a row in an underlying database table. An entity bean’s home interface may contain both finder methods and create methods.
Finder methods Finder methods look return instances that match an existing row in the underlying database.
A home interface may contain several finder methods, each of which accepts parameters to constrain the search for matching database rows. Every entity bean home interface has a findByPrimaryKey method that accepts a structure that represents the primary key for a row to look up.
Finder methods throw CtsComponents::FinderException if no rows match the specified search criteria.
Create methods Create methods insert a row into the underlying database.
When instantiating an entity bean proxy, call a finder method first if you are not sure whether an entity bean’s data is already in the database. Create methods throw a CtsComponents::CreateException exception if you attempt to insert a duplicate database row.
Example: instantiating an entity bean This example instantiates an entity bean that represents a customer credit account. The primary key structure has two members: custName is a string and creditType is also a string. The example looks for a customer named "Morry" using the findByPrimaryKey method. If a user exception is raised, the code assumes that CtsComponents::FinderException was thrown to indicate that the requested entity does not exist. In this case, the example calls a create method to create a new entity.
Dim pKey As bookStore.custCreditKey Dim customerName as String customerName = "Morry" Set pKey = New bookStore.custCreditKey pKey.creditType = "VISA" pKey.custName = customerName Dim balance As Long ' First try to look up the customer as an existing entity ' This fails with CtsComponents::FinderException if the ' entity does not exist. On Error GoTo FinderError Set customer = home.findByPrimaryKey(pKey) GoTo Instantiated FinderError: ' An error 9000 means a user-defined exception was thrown. ' In this case, it must be CtsComponents::FinderException, ' which indicates the requested entity does not exist. Any ’ other error number is unexpected. If Err.Number <> 9000 Then ' This is an unexpected error inError = True Call MsgBox("Error calling findByPrimaryKey", "Error") GoTo CleanupAfterFailure End If ' Create a new entity. Create methods are not overloaded in the ’ IDL home interface, and we must use the full IDL method name. On Error GoTo CleanupAfterFailure balance = 3000 Set customer = home.create__string(customerName, balance) Instantiated: ' Successful instantiation. Code to call business methods goes here. CleanupAfterFailure: ' Unexpected error. Code to clean up forms, display errors, ’ and so forth.
The home interface for a session bean contains only create methods.
The example below instantiates a home interface named HelloWorldHome/HelloWorldHome, then calls the create method that takes no parameters. The IDL home interface type is mde::helloworld::HelloWorldHome and the remote interface is mde::helloworld::HelloWorld.
Dim session as SessionManager.Session ... deleted code that instantiated a valid session ... Dim compHome As mde_helloworld.HelloWorldHome Set CORBAObj = session.lookup("HelloWorldHome/HelloWorldHome") Set compHome = CORBAObj.Narrow_("mde/helloworld/HelloWorldHome") Set comp = compHome.Create().Narrow_("mde/helloworld/HelloWorld")
An EJB client can obtain a handle for a remote interface instance. The handle is a binary encoding of the session state between the client and the component. The client can obtain a handle, save it to disk or mail it to another location, then reestablish the session at a later time.
In a CORBA client, you can obtain the same functionality using the Orb.object_to_string and Orb.string_to_object methods. The same restrictions apply when deserializing component proxies that apply to any other remote object.
|Copyright © 2005. Sybase Inc. All rights reserved.|