Calling a Java Class from PowerBuilder 10
Introduction
This whitepaper discusses how to call a stand-alone Java class from within a PowerBuilder application, including how to deal with exceptions and returning values back to PowerBuilder from the Java class.
Getting Started
Before you can start communicating with java classes from PowerBuilder you must add a file to your library list. This file is
pbejbclient100.pbd and it can typically be found in
C:/Program Files/Sybase/Shared/PowerBuilder/. Once you have this file in your library list you will be able to declare and create the Java VM and EJBConnection classes that are required to talk to a Java class.
At runtime PowerBuilder must also be able to find two other files, jvm.dll and pbjvm100.dll.
Creating the Java Class
There’s nothing special you need to do when creating the Java classes that you wish to access, there is however some issues you need to consider which are covered in Handling Exceptions and Returning Arguments.
To start with I have created a simple Java class with one method that will add two ints passed as arguments and return the result also as an int to demonstrate the use of Java in PowerBuilder:
public class JavaPBTest {
public int add( int _number1, int _number2 ) {
return _number1 + _number2;
}
}
Before we can instantiate the java class and call it from PowerBuilder, we must fool PowerBuilder into thinking we are using an EJB, therefore we have to create a dummy home interface for the class. The home interface for my class would look like this:
public interface JavaPBTestHome{}
We can now compile our two Java classes and move on to the next stage.
Creating the PowerBuilder Code
Creating a Proxy
Before we can instantiate our Java class in PowerScript we must create a proxy object for the java class. This is achieved by creating an EJB Client Proxy object (you can also use the wizard):
Once you have the proxy object you must specify the properties for the object using the Select Objects and Properties toolbar buttons (Edit..Select Objects and Edit..Properties menu items).
The Select Objects option is where you configure how PowerBuilder is to find your Java class and using our simple Java class we would enter the following data:
Note that the fully qualified name is the name including the package name so if we changed our Java class to reside in the package au.com.sybase i.e.
package au.com.sybase;
public class JavaPBTest {
public int add( int _number1, int _number2 ) throws Exception {
if( _number1 == 0 || _number2 == 0 ) {
throw new Exception( "Argument is zero" );
}
else {
return _number1 + _number2;
}
}
}
Then we need to also change the fully qualified class name and interface class name to:
The next step is to specify which library the various objects that PowerBuilder will create as part of the proxy process should be created in. This is done in Properties:
Once you have specified these options, choose Deploy to create the proxy, the process may take a minute or so.
Specifying a JDK
By default PowerBuilder will be installed with a version of Java and this can be used if desired. However you may also want to choose a different JDK and this can be done using the Set JDK Location button of the Java tab of System Options:
As I’m using the default JDK to compile my class I have kept the default settings.
Note that you have to close down PowerBuilder before any changes to the JDK will take effect.
Writing the PowerScript
Now that we have the proxy we can create the PowerScript to instantiate and call our object. In order to do this we must do the following things
Create an instance of the Java VM (providing class path if not already set for the VM)
Create an instance of the EJBConnection class
Create the instance of the Java class
The code below shows an example of the PowerScript required to achieve the above:
INTEGER li_result
INTEGER li_return
EJBConnection l_EJBConnection
JavaVM l_jvm
javapbtest l_javapbtest
// Create an instance of JavaVM class
l_jvm = CREATE JavaVM
// Start the JavaVM
li_return = l_jvm.createJavaVM( "C:/PBJAVA", FALSE )
// Check the return code
CHOOSE CASE li_return
CASE 0, 1
// OK
CASE -1
MessageBox( "Unable to Create JVM", "jvm.dll was not found in the classpath." )
CASE -2
MessageBox( "Unable to Create JVM", "pbejbclient90.jar file was not found." )
CASE ELSE
MessageBox( "Unable to Create JVM", "Unknown error." )
END CHOOSE
IF li_return = 0 OR li_return = 1 THEN
// JavaVM created - Create EJBConnection
l_EJBConnection = CREATE EJBConnection
// Instantaite the Java class.
li_return = l_EJBConnection.createJavaInstance( l_javapbtest, "javapbtest" )
CHOOSE CASE li_return
CASE -1
MessageBox( "Can’t Create Java Class", "Failed to create Java class.")
CASE -2
MessageBox( "Can’t Create Java Class", " Invalid proxy name.")
CASE -3
MessageBox( "Can’t Create Java Class", "Failed to create proxy object.")
CASE 0
// All ok, call Java class method.
li_result = l_javapbtest.add( 50, 60 )
messagebox( "Java Result", STRING(li_result ) )
END CHOOSE
END IF
// Clean up
DESTROY l_EJBConnection
DESTROY l_jvm
DESTROY l_javapbtest
Handling Exceptions and Returning Arguments
My simple Java class is currently returning an argument and PowerBuilder will happily deal with this and translate Java types to PowerBuilder types. PowerBuilder will also handle exceptions and convert them to PowerBuilder exceptions so we could expand our Java class as follows:
public class JavaPBTest {
public int add( int _number1, int _number2 ) throws Exception {
if( _number1 == 0 || _number2 == 0 ) {
throw new Exception( "Argument is zero" );
}
else {
return _number1 + _number2;
}
}
}
To catch and handle the exception we expand our PowerBuilder code to include a Try and Catch block as follows:
TRY
li_result = l_javapbtest.add( 0, 0 )
messagebox( "Java Result", STRING(li_result ) )
CATCH( Throwable t )
MessageBox( "method call failed", t.getMessage() )
END TRY
Changing the Java Class
Overtime we may change our class including adding new methods or perhaps just changing the body of a method. If you change a method definition or add new methods then you will need to re-create the proxy objects using the proxy project you have created.
You can change the body of a method (not the definition), recompile and re-deploy the class without recreating the proxy objects, but in development you would need to shutdown and restart PowerBuilder before the new version of the class would be executed.