Using generated Java classes
Once you’ve generated Java representations of your
user objects, you can use them in an application written in Java
as you would any other classes, by writing Java code that uses the
functions exposed in the class.
Deploying Java classes When you deploy the Java client application, you must also
deploy the files containing the com.sybase.dpb and com.objectspace.jgl
class libraries. The libraries are located in subdirectories of
the SybaseShared directory in the following JAR files:
JDPBlib70.jar and jgl3.1.0.jar.
Remember Do not edit the Java source files generated by PowerBuilder.
To code a Java application using generated classes:
-
Using your Java development tool (these
examples assume PowerJ), create a new Java project. -
Define global variables for JDPB_Connection
and your generated object:1JDPB_Connection myConnection = null;1n_cst_gentest myGentest = null; -
Instantiate the JDPB_Connection class:
1Integer portNo = new Integer(10097);1String hostName = new String("tst.sybase.com");1String userID = new String("rnielsen");1String userPass = new String("mypass");1String connectString = new String("fromJava");1try {1myConnection = new JDPB_Connection(hostName,1portNo.intValue(), userID,1userPass, connectString);1}1catch(java.lang.Throwable e) {1lb_1.add("Exception");1lb_1.add(e.getMessage());1}
(For other ways of instantiating the JDPB_Connection
class, see “Establishing a connection”.) -
Instantiate the generated object, passing the
JDPB_Connection instance to the constructor:1myGentest = new n_cst_gentest(myConnection); -
Call user object functions from the Java application:
1String argString = textf_3.getText();1if (argString.equals("")) {1lb_1.add("Must type in text field");1}1try {1String returnValue =1myGentest.f_stringreturn(argString);1if (returnValue.equals("")) {1lb_1.add("Error. Empty string returned");1} // end if1else lb_1.add( returnValue );1} //end try11catch (com.sybase.dpb.RemoteException e) {1lb_1.add("RemoteException exception");1lb_1.add(e.getMessage());1} // end catch
RemoteException All generated methods throw the RemoteException exception.
-
Disconnect from the server application when you
have finished:1myConnection.disconnect();You must disconnect You must disconnect from the server application before closing
the client application. Failure to explicitly disconnect will leave
Java threads open and can cause a Java application to hang.
Setting up the Java project
Once you have generated Java classes, you use them in a Java
project as you would any other classes.
To set up a Java project for use with generated
Java classes:
-
Using your Java development tool (these
examples assume PowerJ), create a new Java project.This project should use version 1.1.7 of the JDK. The JDKin
directory must be in your PATH environment variable. -
Add the directory containing com.sybase.dpb to
the ClassPath. -
Add the directory containing COM.objectspace.jgl
to the ClassPath. -
Add the directory containing the generated package
to the ClassPath.or
Include the generated file (or files) in your Java project.
-
Code import statements for com.sybase.dpb and
your generated package (com.sybase.PBClasses in this example):1import com.sybase.dpb.*;1import com.sybase.PBClasses.*;
Establishing a connection
The com.sybase.dpb package contains the JDPB_Connection
class, which your Java application uses to communicate with the PowerBuilder server application.
Properties
The connection class requires the following properties:
- Server application port number
- Server application address (IP address, URL, or
localhost) - User ID (used by server application ConnectionBegin
event) - Password (used by server application ConnectionBegin
event) - Connect string (used by server application ConnectionBegin
event)
How to provide
You provide these properties in one of these ways:
- In the constructor
- Individually
- In the connect method
- Using JavaBeans persistence
You must explicitly disconnect You must disconnect from the server application before closing
the client application. Failure to explicitly disconnect will leave
Java threads open and can cause a Java application to hang.
The Throwable exception
The JDPB_Connection connect method and certain JDPB _Connection constructors
throw the Throwable exception.
Setting connection properties in the constructor
When you provide connection properties in the JDPB_Connection
constructor, the constructor also connects to the PowerBuilder server
application.
This example assumes a global variable myConnection of type JDPB_Connection:
1 |
Integer portNo = new Integer(10097); |
1 |
String hostName = new String("tst.sybase.com"); |
1 |
String userID = new String("rnielsen"); |
1 |
String userPass = new String("mypass"); |
1 |
String connectString = new String("fromJava"); |
1 |
1 |
try { |
1 |
myConnection = new JDPB_Connection(hostName, |
1 |
portNo.intValue(), userID, |
1 |
userPass, connectString); |
1 |
} |
1 |
catch(java.lang.Throwable e) { |
1 |
lb_1.add("Exception"); |
1 |
lb_1.add(e.getMessage()); |
1 |
} |
Setting connection properties individually
After setting connection properties individually, you call
the JDPB_Connection connect method.
This example assumes a global variable myConnection of type JDPB_Connection:
1 |
myConnection = new JDPB_Connection(); |
1 |
myConnection.setServerAddress(hostName); |
1 |
myConnection.setPort(portNo.intValue()); |
1 |
myConnection.setUserId(userID); |
1 |
myConnection.setPassword(userPass); |
1 |
myConnection.setConnectString(connectString); |
1 |
1 |
try { |
1 |
myConnection.connect(); |
1 |
} catch(java.lang.Throwable e) { |
1 |
lb_1.add("connect exception"); |
1 |
lb_1.add(e.getMessage()); |
1 |
} |
Setting connection properties in the connect method
You can also establish a connection by passing arguments to
the JDPB_Connection connect method:
1 |
Integer portNo = new Integer(10097); |
1 |
String hostName = new String("tst.sybase.com"); |
1 |
String userID = new String("rnielsen"); |
1 |
String userPass = new String("mypass"); |
1 |
String connectString = new String("fromJava"); |
1 |
myConnection = new JDPB_Connection(); |
1 |
1 |
try { |
1 |
myConnection.connect(hostName, |
1 |
portNo.intValue(), userID, |
1 |
userPass, connectString); |
1 |
}catch(java.lang.Throwable e) { |
1 |
lb_1.add("connect exception"); |
1 |
lb_1.add(e.getMessage()); |
1 |
} |
Setting connection properties using JavaBeans persistence
Because JDPB_Connection is a JavaBeans-compliant
class, you can use JavaBeans persistence to simplify connection
processing.To take advantage of JavaBeans features such as persistence,
it’s best to use a Java development environment (such as PowerJ)
that supports JavaBeans. These instructions assume that you are
using such a tool.
To use JavaBeans persistence with JDPB_Connection:
-
Add JDPB_Connection to your Java
development environment’s toolbar or palette, as described
in Integrating generated classes
with the PowerJ reference card. -
Add JDPB_Connection to the form by clicking
on the toolbar icon and then clicking in the form. -
(Optional) Use the Properties dialog box to specify
a shorter name for the JDPB_Connection instance (myConnection
in this example). -
Use the Object Inspector to set JDPB_Connection
properties. -
(Optional) Override default JDPB_Connection
specifications programmatically.This example overrides the default user ID and password:
1myConnection.setUserID(textf_ID.getText());1myConnection.setPassword(textf_PW.getText()); -
Call the connect method programmatically:
1try {1myConnection.connect();1}1catch(java.lang.Throwable e) {1lb_1.add("Exception");1lb_1.add(e.getMessage());1}
-
Instantiate your user object, passing the JDPB_Connection
instance to the constructor:1myGentest = new n_cst_gentest(myConnection);
In practice, you probably want to use persistence for the
server address and port number, allowing your execution-time code
to set the user ID, password, and connect string before calling
the connect method.
Calling methods in the JavaBeans proxy
Once you have established a connection and instantiated the
JavaBeans proxy, your Java program can access the user object’s
public instance variables and public functions.
To call methods in the JavaBeans proxy:
- Establish a connection as described in “Establishing a connection”.
-
Instantiate the generated object, passing the
JDPB_Connection instance to the constructor:1myGentest = new n_cst_gentest(myConnection); -
Initialize values for function arguments:
1String argString = textf_3.getText();1if (argString.equals("")) {1lb_1.add("Must type in text field");1}
-
Call the user object function from within a try
block:1try {1String returnValue =1myGentest.f_stringreturn(argString);1if (returnValue.equals("")) {1lb_1.add("Error. Empty string returned");1} // end if1else {1lb_1.add( returnValue );1} // end else1} // end try -
Code a catch block for the RemoteException exception:
1catch (com.sybase.dpb.RemoteException e) {1lb_1.add("RemoteException exception");1lb_1.add(e.getMessage());1} // end catch
RemoteException All generated methods throw the RemoteException exception.
Handling arguments by reference
The classes generated by the JavaBeans proxy generator use
a set of holder classes to enable passing of arguments by reference.
When passing reference arguments, you pass the holder class instead
of the data type’s class. There are two holder classes
for each data type: one for the data type itself and one for arrays
of that data type:
PowerScript data type | Java class | Holder class | Array Holder class |
---|---|---|---|
Blob | Blob | BlobHolder | BlobArrayHolder |
Boolean | Boolean | BooleanHolder | BooleanArrayHolder |
Char | Char | CharacterHolder | CharacterArrayHolder |
Date | Date | DateHolder | DateArrayHolder |
DateTime | DateTime | DateTimeHolder | DateTimeArrayHolder |
Decimal | BigDecimal | BigDecimalHolder | BigDecimalArrayHolder |
Double | Double | DoubleHolder | DoubleArrayHolder |
Integer | Short | ShortHolder | ShortArrayHolder |
Long and UnsignedInteger | Integer | IntegerHolder | IntegerArrayHolder |
Real | Float | FloatHolder | FloatArrayHolder |
String | String | StringHolder | StringArrayHolder |
Time | Time | TimeHolder | TimeArrayHolder |
UnsignedLong | Long | LongHolder | LongArrayHolder |
For more information about these classes,
see “About the com.sybase.dpb
package” and
the online Help for the Java proxy generator.
Additionally, the JavaBeans proxy generator generates two
holder classes for each global structure used by your custom class
user object.
Before the function call, initialize the holder class either
through the constructor or the holder class setValue method. After
the function call completes, access the reference value by calling
the holder class getValue method. The following example passes two
strings, one by value and one by reference.
To call a function that uses arguments by reference:
-
Define variables:
1String arg1String; // Arg1 is pass by value1String arg2String; // Arg2 is pass by ref1String displayString;
-
Define values for the variables:
1arg1String = textf_1.getText();1arg2String = textf_2.getText();
-
Define and initialize the holder variable with
the value to be passed by reference:1StringHolder arg2Holder = new1StringHolder(arg2String); -
Call the function. After calling the function,
access the reference value by calling the holder class getValue
method:1try {1Short returnValue =1myGentest.f_stringbyref(arg1String,1arg2Holder);1displayString = "Arg1 = " + arg1String +1". Arg2 = " + arg2Holder.getValue();1lb_1.add( displayString );1} // end try1catch (com.sybase.dpb.RemoteException e) {1lb_1.add("RemoteException exception");1} // end catch -
(Optional) Reuse the holder variable by calling
the holder class setValue method:1arg2Holder.setValue(newArg2String);
Handling global structures
The JavaBeans proxy generator creates three classes for each
global structure used by your custom class user object: one to contain
the structure, one for passing a single instance of the structure
by reference, and one for passing arrays of the structure by reference.
For example, if your custom class user object uses the str_name
structure as an argument, return value, or public instance variable,
the JavaBeans proxy generator creates the following Java classes:
Class name | Usage |
---|---|
str_nameinfo | Contains the structure |
str_nameinfoHolder | Use when passing the structure by reference |
str_nameinfoArrayHolder | Use when passing arrays of the structure by reference |
To pass a structure by value:
-
Define variables, including an instance
of the structure class:1str_nameinfo myNameinfo = new str_nameinfo();1Integer myInt = new Integer(23); -
Initialize the structure:
1myNameinfo.l_id = myInt;1myNameinfo.s_fname = "William";1myNameinfo.s_lname = "Browne";
-
Call the function, passing the structure:
1try {1String sReturn = new String1(myGentest.f_structargbyvalue(myNameinfo));1lb_1.add(sReturn);1}1catch (RemoteException e) {1lb_1.add("RemoteException exception");1}
To pass a structure by reference:
-
Define variables, including an instance
of the structure class:1str_nameinfo myNameinfo = new str_nameinfo( ); -
Initialize the structure:
1myNameinfo.l_id = new Integer(23);1myNameinfo.s_fname = "Jackson";1myNameinfo.s_fname = "Brown";
-
Define a variable for the structure’s
holder class, passing the structure instance to the holder class’s
constructor:1str_nameinfoHolder myNameinfoHldr = new1str_nameinfoHolder(myNameinfo); -
Call the function, passing the structure’s
holder class:1try {1Short myShort = new Short((short)23);1myGentest.f_structargbyref1(myShort, myNameinfoHldr);1}1catch (RemoteException e) {1lb_1.add("RemoteException exception");1} -
Copy values from the updated holder class back
to the structure, casting the holder class’s getValue method
to the type of the structure:1myNameinfo =1(str_nameinfo)myNameinfoHldr.getValue();1lb_1.add(myNameinfo.l_id.toString());1lb_1.add(myNameinfo.s_fname);1lb_1.add(myNameinfo.s_lname);
To use a structure as a return value:
-
Define variables, including an instance
of the structure class:1int arg1Int;1String arg1String;1str_nameinfo lstrNameInfo = new str_nameinfo();1Integer arg1 = new Integer(100); -
Call the function:
1try {1lstrNameInfo = myGentest.f_returnstruct(arg1);1lb_1.add( lstrNameInfo.l_id.toString() );1lb_1.add( lstrNameInfo.s_fname );1lb_1.add( lstrNameInfo.s_lname );1} // end try11catch (com.sybase.dpb.RemoteException e) {1lb_1.add("RemoteException exception");1lb_1.add(e.getMessage());1} // end catch
To pass an array of structures by reference:
-
Define variables, including an instance
of the structure class and an instance of the structure array holder
class:1Integer deptID = null;1Integer numRows = null;1str_nameinfo nameInfo[] = new str_nameinfo[1];1str_nameinfoArrayHolder nameInfoArrayHolder1= new str_nameinfoArrayHolder(nameInfo);1String returnedID = null;1String returnedAll = null;1int rowCounter; -
Initialize data and call the function:
1deptID = new Integer(textf_1.getText());1lb_1.clear();1try {1numRows = myGenTest.f_returnstructarray(deptID,1nameInfoArrayHolder);1nameInfo = (str_nameinfo[]);1nameInfoArrayHolder.getValue();1for (rowCounter = 0; rowCounter <1numRows.intValue(); rowCounter++)1{1returnedID =1nameInfo[rowCounter].l_id.toString();1returnedAll = "ID: " + returnedID + " " +1nameInfo[rowCounter].s_fname + " " +1nameInfo[rowCounter].s_lname;1lb_1.add(returnedAll);1} // end for1} // end try11catch(RemoteException e) {1lb_1.add("RemoteException exception");1lb_1.add(e.getMessage());1} // end catch
Handling arrays
Arrays passed by value require no special handling. The com.sybase.dpb library
contains special holder classes for use when passing arrays by reference.
To pass an array by reference:
-
Declare variables:
1Integer deptID = null;1Integer numRows = null;1Integer idIn[] = new Integer[1];1// dummy array for refIn1String fnameIn[] = new String[1];1// dummy array for refIn1String lnameIn[] = new String[1];1// dummy array for refIn1String returnedID = null;1String returnedAll = null;1int rowCounter;
-
Initialize values as necessary:
1deptID = new Integer(textf_1.getText());1lb_1.clear();
-
Initialize the holder class, passing the array
to its constructor (this example initializes three array holder
instances):1IntegerArrayHolder idHolder =1new IntegerArrayHolder(idIn);1StringArrayHolder fnameHolder =1new StringArrayHolder(fnameIn);1StringArrayHolder lnameHolder =1new StringArrayHolder(lnameIn); -
Call the function, passing the holder class:
1try {1numRows = myGenTest.f_returnthreearraysunbounded1(deptID, idHolder, fnameHolder, lnameHolder);
-
Call the holder class getValue function to access
the returned array:1Integer[] idList =1(Integer[])idHolder.getValue();1String[] fnameList =1(String[])fnameHolder.getValue();1String[] lnameList =1(String[])lnameHolder.getValue(); -
Access array elements as necessary:
1for (rowCounter = 0; rowCounter <1numRows.intValue(); rowCounter++)1{1returnedID = idList[rowCounter].toString();1returnedAll = "ID: " + returnedID + " " +1fnameList[rowCounter] + " " +1lnameList[rowCounter];1lb_1.add(returnedAll);1} // end for1}// end try
-
Code the catch block for RemoteException:
1catch(RemoteException e) {1lb_1.add("RemoteException exception");1lb_1.add(e.getMessage());1}
Handling null values
Because the JavaBeans proxy generator implements all PowerScript
data types as Java classes, null value coding is simplified. To
pass a null value, set it to null before calling the function:
1 |
... |
1 |
myShort = null; |
1 |
myObject.f_sendnull(myShort); |
1 |
... |
If a function has an output argument that can return a null
value, check to see if it is null when the function completes:
1 |
... |
1 |
myObject.f_getnull(myShort); |
1 |
if (myShort = null) { |
1 |
// null processing |
1 |
} |
1 |
... |
Using the Date and DateTime classes
Java date support differs from PowerBuilder date and datetime
support. The biggest differences are:
- The Java
Date class accepts a year relative to 1900. For example, specify 1998
as 98, specify 2001 as 101, and specify 1492 as -408. - The Java Date class accepts a zero-based month.
0 is January, 1 is February, and so on.
To use the Date class:
-
Define a variable of type Date.
1com.sybase.dpb.Date myDate;
-
Create an instance of the variable.
1// This example creates 1998/3/181myDate = new com.sybase.dpb.Date((short)98,1(byte)2, (byte)18);
To use the DateTime class:
-
Define a variable of type DateTime.
1com.sybase.dpb.DateTime myDateTime;
-
Create an instance of the variable.
1// This example creates 2001/3/15 20:15:10:991myDateTime = new com.sybase.dpb.DateTime(1(short)101, (byte)2, (byte)15, (byte)20,1(byte)15, (byte)10, (int)99);