JavaVM

Description

The JavaVM class provides a method for loading and initializing a Java VM. It also provides methods for obtaining the version of the Java VM and the classpath it is using, to get the class name, super class name, and interface name of a Java class from the PowerBuilder proxy for that class, and to down cast a PowerBuilder proxy to another PowerBuilder proxy.

PowerBuilder 2017 R3 is compatible with Java VM 1.6 only (not 1.7 or 1.8).

Methods

JavaVM has the following member functions:

CreateJavaVM

CreateJavaInstance

DynamicCast

GetActualClass

GetInterfaces

GetJavaClasspath

GetJavaVMVersion

GetSuperClass

IsJavaVMLoaded

LoadMappingTable

CreateJavaVM

Description

Loads and initializes a Java VM or attaches an existing Java VM to the current process.

Syntax

javavm.createJavaVM(string classpath, boolean isdebug)

Argument

Description

javavm

An instance of the JavaVM class

classpath

A string specifying the classpath that contains files required by the EJB server, such as the path to the EJB classes

isdebug

A boolean that determines whether debug information is saved to a file called VM.out in the directory where the current application is located


Return value

Integer.

Returns one of the following integer values:

1 -- Success. The Java VM had already been loaded and was attached to the current process.

0 -- Success. The Java VM was loaded and initialized and attached to the current process.

-1 -- Failure. The Java VM was not loaded, possibly because jvm.dll was not found in the classpath.

-2 -- Failure. The pbejbclient170.jar file was not found.

Examples

This example shows how createJavaVM might be used with a connection to WebLogic:

JavaVM l_jvm
EJBConnection l_ejbconn
java_integer val
l_jvm = CREATE JavaVM
l_EJBConn = CREATE EJBConnection

TRY
  IF l_jvm.createJavaVM("", false) >= 0 THEN
    string ls_props[]
    ls_props[1] = "javax.naming.Context.INITIAL_CONTEXT_FACTORY=
      weblogic.jndi.WLInitialContextFactory"
    ls_props[2] ="javax.naming.Context.PROVIDER_URL=t3://svr1:7001"
    ls_props[3] = "javax.naming.Context.SECURITY_PRINCIPAL=myid"
    ls_props[4] = "javax.naming.Context.SECURITY_CREDENTIALS=mypass"
    l_EJBConn.connectToServer(ls_props)
    l_EJBConn.createJavaInstance(val, "java_integer")
    val.java_integer(17)
    MessageBox("The value is", val.IntValue())
  ELSE
    MessageBox("createJavaVM", "Failed", StopSign!)
  END IF
CATCH (Throwable g)
  MessageBox("Exception in createJavaInstance", g.getMessage())
END TRY

Usage

The isdebug argument is used to record information about the Java VM, including class loads, in the file VM.out in the directory where the current application is located.

The classpath argument must include the classes and JAR files required by the server, if they are not already listed in the classpath used by the Java VM.

Classpath argument has no effect if the JVM is already running

Files and directories passed only in the classpath argument are not available to the Java VM if it has already been started by another process. In the development environment, you can check whether the Java VM is running and, if so, which classpath it is using, on the Java page of the System Options dialog box. At runtime, you can use the IsJavaVMLoaded method to determine whether the Java VM is already running, and the GetJavaClasspath method to find the classpath.

In the development environment, the classpath used by the Java VM is constructed by concatenating these paths:

  • A classpath added programmatically when the JVM is started. For example, the classpath you pass to this method.

  • The PowerBuilder runtime static registry classpath. This path is built into the pbjvm170.dll and contains classes required at runtime for features such as PDF generation and EJB clients.

  • The PowerBuilder system classpath. This path resides in a Windows registry key installed when you install PowerBuilder. It contains classes required at design time for Java-related PowerBuilder features.

  • The PowerBuilder user classpath. This is the path that you specify on the Java page of the System Options dialog box.

  • The system CLASSPATH environment variable.

  • The current directory.

The JVM uses the following classpath at runtime:

  • A classpath added programmatically when the JVM is started

  • The PowerBuilder runtime static registry classpath

  • The system CLASSPATH environment variable

  • The current directory

See also

ConnectToServer

GetJavaClasspath

GetJavaVMVersion

IsJavaVMLoaded

CreateJavaInstance

Description

Creates an instance of a Java object from a proxy name.

Syntax

javavm.CreateJavaInstance (powerobject proxyobject, string proxyname ) 

Argument

Description

javavm

An instance of the JavaVM class.

proxyobject

PowerObject into which the function places a reference to the object specified by proxyname. This argument is passed by reference.

proxyname

The name of the proxy object for the local Java class.


Return value

Long.

Returns 0 for success and one of the following values for failure:

-1 -- Failed to create Java class.

-2 -- Invalid proxy name.

-3 -- Failed to create proxy object.

Examples

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:

CustomerRemoteHome homeobj
CustomerRemote beanobj
java_integer jint_a

try
  homeobj = conn.lookup("CustomerRemoteHome", &
    "custpkg/Customer", "custpkg.CustomerRemoteHome" )
catch (Exception e)
   MessageBox( "Exception in Lookup", e.getMessage() )
   return
end try

try
   g_jvm.createJavaInstance(jint_a, "java_integer")
   jint_a.java_integer("8")
   beanobj = homeobj.create( jint_a, sle_name.text )
catch (RemoteException re)
   MessageBox( "Remote Exception", re.getMessage() )
   return

catch (CreateException ce)
   MessageBox( "Create Exception", ce.getMessage() )
   return
catch (Throwable t)
   MessageBox(" Other Exception", t.getMessage())
end try

MessageBox( "Info", &
   "This record has been successfully saved " &
   + "~r~ninto the database" )

Usage

Use this method when an EJB method accepts a Java class as an argument. For example, if the primary key class argument to the findByPrimaryKey method is a Java class, use the CreateJavaInstance method to create the primary key class. You then use a PowerBuilder proxy to communicate with the Java class.

DynamicCast

Description

Converts an instantiated PowerBuilder proxy object to a proxy for the passed-in proxy name.

Syntax

javavm.DynamicCast(powerobject proxyobject, readonly string proxyname)

Argument

Description

javavm

An instance of the JavaVM class

proxyobject

An instantiated PowerBuilder proxy object

proxyname

A string containing the name of the proxy to be instantiated


Return value

Powerobject.

A new proxy object for the Java class referenced by proxyname. This method returns null if the proxy cannot be created.

Examples

  1. In the following example, the object returned from the nextElement method is represented by a proxy for the Employee class. The GetActualClass method is used to determine whether the object is actually a SalariedEmployee, and if it is, the proxy px_Employee is down cast to the proxy px_SalariedEmployee so that the adjustSalary method can be called:

    DepartmentHome   px_DeptHome
    Department       px_Dept
    Enumeration      px_EmployeeList
    Employee         px_Employee
    Salaried         px_SalariedEmployee
    Contract         px_ContractEmployee
    EJBConnection    conn
    
    conn = create ejbconnection
    try
       conn.connectToServer(properties)
       px_DeptHome = conn.lookup("DepartmentHome",  &
          "Department",   &
          "com.joesportinggoods.ejbs.DepartmentHome")
       px_Dept = px_DeptHome.findByPrimaryKey(as_DeptName)
    
       px_EmployeeList = px_Dept.getEmployees()
       DO WHILE px_EmployeeList.hasMoreElements()
         px_Employee = px_EmployeeList.nextElement()
         IF i_jvm.getActualClass(px_Employee) =  &
            "com.joesportinggoods.ejbs.Salaried" THEN
             px_SalariedEmployee =   &
                i_jvm.dynamicCast(px_Employee, "Salaried")
             px_SalariedEmployee.adjustSalary(al_increase)
         END IF
       LOOP
    catch (Exception e)
       THROW CREATE ApplyRaiseException
    end try
  2. In this example, getAllItems returns a java.lang.Object in the EJB declaration, which maps to the PowerBuilder Any data type. The call to GetInterfaces determines whether what is returned is a java.util.List. If it is, a call to DynamicCast obtains a proxy for List, which is used to obtain the size of the list before using its Get method to obtain the elements of the list. A method such as getAllItems can be used in many situations, such as to get a list of part numbers for any type of product.

    ItemManagerHome px_ItemMgrHome
    ItemManager px_ItemMgr
    Item px_Item
    List px_ItemList
    any any_Object
    boolean ib_isAList = FALSE
    string is_IFs[]
    string is_actualClass
    long ll_row
    
    TRY
       px_ItemMgrHome =      g_EJBConn.Lookup("ItemManagerHome", &
         "ItemManager","com.xapic.ItemManagerHome")
       px_ItemMgr = px_ItemMgrHome.create()
       any_Object = px_ItemMgr.getAllItems()
    // check if object implements java.util.List interface
       integer i
       FOR i = 1 to g_javaVM.getInterfaces(any_Object, &
         is_IFs)
         IF is_IFs[i] = "java.util.List" THEN
            ib_isAList = TRUE
            EXIT
         END IF
       NEXT
       // if it is a list
       IF ib_isAList THEN
         px_ItemList = g_javaVM.dynamicCast(any_Object, &
            "list")
         // traverse the list
          FOR i = 0 TO px_ItemList.size() - 1
            // get item on the list
            any_Object = px_ItemList.get(i)
             // determine its class and dynamically cast it
            is_actualClass = &
               g_javaVM.getActualClass(any_Object)
            is_actualClass = Mid(is_actualClass, &
               LastPos(is_actualClass,".") + 1, &
               Len(is_actualClass))
            px_Item = g_javaVM.dynamicCast(any_Object,            is_actualClass)
            // add item to datastore
            ll_row = ads_Items.insertRow(0)
            ads_Items.object.id[ll_row] = px_Item.getID()
            ads_Items.object.type[ll_row] = is_actualClass
          NEXT
       END IF
    CATCH (Throwable t)
       // Handle exception
    END TRY
    

Usage

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, the prototype of a method that actually returns an object of type java.util.ArrayList can be defined to return java.util.Collection instead. (The java.util.ArrayList class inherits from java.util.AbstractList, which inherits from java.util.AbstractCollection, which implements java.util.Collection.) If the method prototype has a return type of java.util.Collection, 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, consider the following class:

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.

See also

CreateJavaVM

GetActualClass

GetInterfaces

GetSuperClass

GetActualClass

Description

Returns the class of the Java object that a PowerBuilder proxy object represents.

Syntax

javavm.GetActualClass(powerobject proxyobject)

Argument

Description

javavm

An instance of the JavaVM class

proxyobject

An instantiated PowerBuilder proxy object


Return value

String

Usage

If an EJB method is defined to return a Java class that is not the actual object returned at runtime, but is instead a class that the actual object's class extends or implements, you can use GetActualClass to return the class of the actual object returned. You can then use the DynamicCast method to cast the proxy returned from the method to a proxy for the actual class of the object.

For more information and an example, see the description of the DynamicCast method.

See also

CreateJavaVM

DynamicCast

GetInterfaces

GetSuperClass

GetInterfaces

Description

Populates a string array with the names of interfaces implemented by the Java object that a PowerBuilder proxy object represents.

Syntax

javavm.GetInterfaces(powerobject proxyobject, ref string interfacename[ ])

Argument

Description

javavm

An instance of the JavaVM class

proxyobject

An instantiated PowerBuilder proxy object

interfacename[ ]

A reference to an unbounded array of strings to hold the names of interfaces implemented by the Java object represented by the PowerBuilder proxy object


Return value

Integer.

Returns the number of interfaces implemented by the Java object represented by proxyobject. If no interfaces are implemented by the Java object, this method returns 0. If proxyobject is invalid, this method returns -1.

Usage

If a class implements multiple interfaces, the proxy returned from an EJB method call that returns a Java object maps to the first interface implemented by the Java class. This method writes a list of interfaces implemented by the class to an array of strings. It can be used in conjunction with the DynamicCast method to cast the returned proxy to the interface required.

For more information, see the description of the DynamicCast method.

See also

CreateJavaVM

DynamicCast

GetActualClass

GetSuperClass

GetJavaClasspath

Description

Gets the classpath of the current Java VM.

Syntax

javavm.getJavaClasspath( )

Return value

String

Examples

This example shows how to use GetJavaClasspath to get the classpath when the JVM is started and write it to a log file:

// instance variables:
// JavaVM i_jvm
// boolean i_jvm_started = false
// string is_classes

//Start JavaVM and Prepare to Connect to EJB server
string classpath
Integer li_ret

//create JAVAVM
if ib_jvm_started = false then
   i_jvm = create javavm

  classpath = is_classes
  li_ret = i_jvm.createJavaVM(classpath, true)
  if li_ret = -1 then
    MessageBox("Error", "Failed to load JavaVM")
  end if
  if li_ret = -2 then
    MessageBox("Error", "Failed to load EJBLocator")
  end if

  ib_jvm_started = true

  integer li_FileNum
  string ls_classpath, ls_string

  li_FileNum = FileOpen("C:\temp\classpath.log", &
     LineMode!, Write!, LockWrite!, Append!)
  ls_classpath = i_jvm.getjavaclasspath()
  ls_string = String(Today()) + " " + String(Now())
  ls_string += ": ~r~n" + ls_classpath + "~r~n"
  
  FileWrite(li_FileNum, ls_string)
  FileClose(li_filenum)
end if

See also

CreateJavaVM

GetJavaVMVersion

IsJavaVMLoaded

GetJavaVMVersion

Description

Gets the version number of the current Java VM.

Syntax

javavm.getJavaVMVersion( )

Return value

String representing the Java VM version. For example, for JDK 1.4, GetJavaVMVersion returns 1.4.0.

Examples

This example shows how to use GetJavaVMVersion:

// global variable JavaVM g_jvm
string ls_javaVMVersion
ls_javaVMVersion = g_jvm.getJavaVMVersion()

See also

CreateJavaVM

GetJavaClasspath

IsJavaVMLoaded

GetSuperClass

Description

Returns the name of the super class of the class of the Java object that a PowerBuilder proxy object represents.

Syntax

javavm.GetSuperClass(powerobject proxyobject)

Argument

Description

javavm

An instance of the JavaVM class

proxyobject

An instantiated PowerBuilder proxy object


Return value

String.

If the current Java object is Java.lang.Object or an interface, returns null.

Examples

This example assumes that you have subclassed the Java Decimal class. Your class, My.Decimal, extends java.lang.Decimal. After you build a proxy project for this class, you can determine the real Java class name that the proxy represents with code like the following:

java_decimal dec_num
string classname, supername

conn.createjavainstance(dec_num, "java_decimal")
classname = g_javavm.getactualclass(dec_num)   &
   classname = "My.Decimal"
supername = g_javavm.getsuperclass(dec_num) &
   supername = "java.lang.Decimal"

Usage

This method returns the name of the immediate parent of the class referenced by the proxy object. For example, if proxyobject is a java.io.FilterReader, GetSuperClass returns java.io.Reader. GetSuperClass can be used in conjunction with the GetInterfaces and DynamicCast methods to cast a proxy object returned from an EJB method call to a different object.

For more information, see the description of the DynamicCast method.

See also

CreateJavaVM

DynamicCast

GetActualClass

GetInterfaces

IsJavaVMLoaded

Description

Determines whether the Java VM has been loaded.

Syntax

javavm.IsJavaVMLoaded( )

Argument

Description

javavm

An instance of the JavaVM class


Return value

Boolean.

Returns true if the Java VM has already been loaded and false if it has not.

Examples

This example tests whether the Java VM has been loaded before attempting to create and load a Java VM:

if (IsJavaVMLoaded) then
   // skip some processing
else
   // perform processing
end if

Usage

Use this method if you need to determine whether the Java VM is loaded before proceeding. You might want to enable or disable some features of your application if the Java VM has already been loaded. For example, if your application provides a window in which the user can specify a list of classes that is added to the classpath used by the CreateJavaVM method, you can disable this feature if the Java VM has already been loaded, because any changes made in that window would have no effect.

See also

CreateJavaVM

GetJavaClasspath

GetJavaVMVersion

LoadMappingTable

Description

Loads the the mapping table between the Java class and a specified PowerBuilder EJB proxy.

Syntax

javavm.LoadMappingTable(proxyname)

Argument

Description

javavm

An instance of the JavaVM class

proxyname

The name of the proxy object for the local JavaVM class


Return value

Boolean.

Returns true if the mapping table is successfully loaded, and false if the load fails.

Examples

This example creates a Java VM, then tests whether the EJB mapping table has been loaded before attempting to perform operations involving the VM:

JavaVM g_jvm
string classpath
boolean isdebug
foo l_foo
classpath = "D:\tests\javasample\bin;"
isdebug = false
g_jvm.CreateJavaVM(classpath, isdebug)
g_jvm.CreateJavaInstance(l_foo, "foo")
if (LoadMappingTable("foo")) then
  // perform normal processing
else
  // handle failure to load mapping table
end if

Usage

Call LoadMappingTable after calling JavaVM.create, otherwise an exception is thrown.

See also

CreateJavaVM

GetJavaClasspath

GetJavaVMVersion