Invoking component methods
After a connection to the server has been established and
a proxy object or objects created, the client application can begin
using the EJB components. To invoke an EJB
component method, you need to execute the PowerScript statements
required to perform these operations:
-
Use the lookup method
of EJBConnection to access the component’s home interface. -
Invoke the create or findByPrimaryKey method
on the home interface to create or find an instance of the component and
get a reference to the component’s remote interface. -
Invoke the business methods on the remote interface.
This procedure relies on the pbejbclient125.jar file,
which is included in the Java VM classpath automatically at design
time and runtime by the pbjvm125.dll.
Using the lookup method
The lookup method takes three string arguments:
the name of the proxy for the home interface, the JNDI name of the
EJB component, and the fully qualified home interface name of the
EJB component.
The home interface name is the fully qualified class name
of the EJB home interface. For example, if the class’s
location relative to the Java naming context is ejbsample, the home
interface name is ejbsample.HelloEJBHome
.
The following example shows the invocation of the lookup method
for HelloEJB on WebLogic.
1 |
HelloEJBHome homeobj<br> <br>homeobj = conn.lookup("HelloEJBHome",<br>  "ejbsample.HelloEJB", "ejbsample.HelloEJBHome") |
Lookup in EJB servers is case sensitive. Make sure that the
case in the string you specify for the arguments to the lookup method
matches the case on the server.
Creating or finding an instance of an EJB
A session bean is created in response to a client request.
A client usually has exclusive use of the session bean for the duration
of that client session. An entity bean represents persistent information
stored in a database. A client uses an entity bean concurrently
with other clients. Since an entity bean persists beyond the lifetime
of the client, you must use a primary key class name to find an
instance of the entity bean if one exists or create a new instance
if it does not.
For a session bean, you use the proxy object’s create method
to create the instance of the EJB. The create method
can throw CreateException and RemoteException.
Assuming that you have obtained a reference to the home interface
in homeobj, create is used in the same way on
all EJB servers:
1 |
HelloEJB beanobj<br>try<br>  beanobj = homeobj.create()<br>catch (remoteexception re)<br>  MessageBox("Remote exception", re.getmessage())<br>catch (createexception ce)<br>  MessageBox("Create exception", ce.getmessage())<br>end try |
For an entity bean, you provide a primary key. The FindByPrimaryKey method can
throw FinderException and RemoteException.
In this example, the key is the ID of a specific customer that is
passed as an argument to the function:
1 |
try<br>  beanobj = homeobj.findByPrimaryKey(customerID)<br>catch (remoteexception re)<br>  MessageBox("Remote exception", re.getmessage())<br>catch (finderexception fe)<br>  MessageBox("Finder exception", fe.getmessage())<br>end try |
Invoking EJB component methods
When the bean instance has been created or found, you can
invoke its methods. For example:
1 |
string msg<br>msg = beanobj.displaymessage() |
Creating an instance of a Java class
If the bean has a method that accepts a Java class as an argument,
you use the CreateJavaInstance method of the
JavaVM object to create it. For example, if the primary key in a
call to the findByPrimaryKey method is a Java
class, you would use the CreateJavaInstance method
to create that class, and then use a PowerBuilder proxy to communicate
with it.
In this example, the create method accepts
a Java Integer class argument. PowerBuilder
creates a proxy called java_integer (the
prefix java_ is required to prevent
a conflict with the PowerBuilder integer type).
The call to CreateJavaInstance sets the value
of that variable so you can call the EJB create method:
1 |
CustomerRemoteHome homeobj<br>CustomerRemote beanobj<br>java_integer jint_a<br> <br>try<br>  homeobj = conn.lookup("CustomerRemoteHome", &<br>  "custpkg/Customer", "custpkg.CustomerRemoteHome" )<br>catch (Exception e)<br>  MessageBox( "Exception in Lookup", e.getMessage() )<br>  return<br>end try<br> <br>try<br>  g_jvm.createJavaInstance(jint_a, "java_integer")<br>  jint_a.java_integer("8")<br>  beanobj = homeobj.create( jint_a, sle_name.text )<br> <br><br>catch (RemoteException re)<br>  MessageBox( "Remote Exception", re.getMessage() )<br>  return<br>catch (CreateException ce)<br>  MessageBox( "Create Exception", ce.getMessage() )<br>  return<br>catch (Throwable t)<br>  MessageBox(" Other Exception", t.getMessage())<br>end try<br> <br>MessageBox( "Info", &<br>  "This record has been successfully saved " &<br>  + "~r~ninto the database" ) |
Downcasting return values
When
Java code returns a common Java object that needs to be downcast
for use in Java programming, the Java method always sets the return
value as Java.lang.Object. In a PowerBuilder
EJB client proxy, java.lang.Object is mapped
to the any datatype. At runtime, PowerBuilder
gets the correct Java object and indexes the generated mapping structure
to get the PowerBuilder proxy name. The any value
is set as this proxy object. If the returned Java object can map
to a PowerBuilder standard datatype, the any value
is set as the PowerBuilder standard datatype.
Suppose the remote interface includes the method:
1 |
java.lang.Object account::getPrimaryKey() |
and the home interface includes the method:
1 |
account accounthome::findByPrimaryKey(java.lang.String) |
The return value java.lang.Object is
really a java.lang.String at runtime. PowerBuilder
automatically downcasts the return value to the PowerBuilder string datatype:
1 |
any nid<br>try<br>  account beanobj<br>  homeobj = conn.lookup("AccountHome", &<br>    ejb20-containerManaged-AccountHome, &<br>    examples.ejb20.basic.containerManaged.AccountHome)<br>  beanobj = homeobj.create("101", 0, "savings")<br>  nid = beanobj.getPrimaryKey()<br>  accounts = homeobj.findByPrimaryKey(string(nid))<br>catch (exception e)<br>  messagebox("exception", e.getmessage())<br>end try |
Dynamic casting
There
are two scenarios in which a Java object returned from a call to
an EJB method can be represented by a proxy that does not provide
the methods you need:
-
If the class of a Java
object returned from an EJB method call is dynamically generated,
PowerBuilder uses a proxy for the first interface implemented by
the Java class. -
The prototype of an EJB method that actually returns someclass can
be defined to return a class that someclass extends
or implements. For example, a method that actually returns an object
of type java.util.ArrayList can be defined to
return java.util.Collection.java.util.ArrayList,
which inherits from java.util.AbstractList, which
inherits from java.util.AbstractCollection, which
implements java.util.Collection. In this case,
PowerBuilder uses a proxy for java.util.Collection.
The DynamicCast method allows you to cast
the returned proxy object to a proxy for the interface you require,
or for the actual class of the object returned at runtime so that
the methods of that object can be used.
You can obtain the actual class of the object using the GetActualClass method. You
can also use the DynamicCast method with the GetSuperClass method, which
returns the immediate parent of the Java class, and the GetInterfaces method,
which writes a list of interfaces implemented by the class to an
array of strings.
For example, given the following class:
1 |
public class java.util.LinkedList extends java.util.AbstractSequentialList implements java.util.List, java.lang.Cloneable, java.io.Serializable |
GetActualClass returns java.util.LinkedList, GetSuperClass returns java.util.AbstractSequentialList,
and GetInterfaces returns 3 and writes three strings
to the referenced string array: java.util.List, java.lang.Cloneable,
and java.io.Serializable.
Java collection classes
EJB proxy generation
generates Java common collection classes such as Enumeration, Iterator,
Vector, and so forth. PowerBuilder can manipulate these collection
classes in the same way as a Java client.
For example, suppose the home interface includes the following
method with the return value java.util.Enumeration:
1 |
Enumeration accounthome:: findNullAccounts () |
The following code shows how a PowerBuilder EJB client can
manipulate the enumeration class through the PowerBuilder proxy:
1 |
Enumeration enum <br>try<br>  enum = homeobj.findNullAccounts()<br>  if (not enum.hasMoreElements()) then<br>  msg = "No accounts found with a null account type"<br>  end if<br>catch (exception e)<br>  messagebox("exception", e.getmessage())<br>end try |