Rational Developer for System z
Enterprise PL/I for z/OS, Version 3.8, Programming Guide

Writing Java Sample Program #2

This sample program passes a string back and forth between Java and PL/I. Refer to Figure 82 for the complete listing of the jPassString.java program. The Java portion has one Java class, jPassString.java. The native method, written in PL/I, is contained in passString.pli. Much of the information from the first sample program applies to this sample program as well. Only new or different aspects will be discussed for this sample program.

Step 1: Writing the Java Program

Declare the Native Method

The native method for this sample program looks like this:

public native void pliShowString();
Load the Native Library

The Java statement that loads the native library for this sample program looks like this:

 static {
   System.loadLibrary("passString");
 }
Write the Java Main Method

The jPassString class also includes a main method to instantiate the class and call the native method. The main method instantiates jPassString and calls the pliShowString() native method.

This sample program prompts the user for a string and reads that value in from the command line. This is done within a try/catch statement as shown in Figure 82.

Figure 82. Java Sample Program #2 - Passing a String
 // Read a string, call PL/I, display new string upon return
 import java.io.*;

 public class jPassString{

  /* Field to hold Java string                           */
  String myString;

  /* Load the PL/I native library                        */
  static {
          System.loadLibrary("passString");
  }

  /* Declare the PL/I native method                      */
  public native void pliShowString();

  /* Main Java class                                     */
  public static void main(String[] arg) {

    System.out.println(" ");

    /* Instantiate Java class and initialize string      */
    jPassString myPassString = new jPassString();
    myPassString.myString = " ";

    /* Prompt user for a string                          */
    try {
         BufferedReader in = new BufferedReader(
           new InputStreamReader(System.in));

         /* Process until 'quit' received                */
         while (!myPassString.myString.equalsIgnoreCase("quit")) {
           System.out.println(
             "From Java: Enter a string or 'quit' to quit.");
           System.out.print("Java Prompt > ");
           /* Get string from command line               */
           myPassString.myString = in.readLine();
           if (!myPassString.myString.equalsIgnoreCase("quit"))
             {
              /* Call PL/I native method                 */
              myPassString.pliShowString();
              /* Return from PL/I and display new string */
              System.out.println(" ");
              System.out.println(
                  "From Java: String set by PL/I is: "
                + myPassString.myString );
             }
         }
         }  catch (IOException e) {
         }
  }
 }

Step 2: Compiling the Java Program

The command to compile the Java code would look like this:

javac jPassString.java

Step 3: Writing the PL/I Program

All of the information about writing the PL/I "Hello World" sample program applies to this program as well.

Correct Form of PL/I Procedure Name and Procedure Statement

The PL/I procedure name for this program would be Java_jPassString_pliShowString.

The complete procedure statement for the sample program looks like this:

  Java_jPassString_pliShowString:
  Proc( JNIEnv , myjobject )
    external( "Java_jPassString_pliShowString" )
    Options( FromAlien NoDescriptor ByValue );
JNI Include File

The two PL/I include files which contain the PL/I definitions of the Java Native interface are ibmzjni.inc which in turn includes ibmzjnim.inc. These include files are included with this statement:

   %include ibmzjni;

The ibmzjni and ibmzjnim include files are provided in the PL/I SIBMZSAM data set.

The Complete PL/I Procedure

The complete PL/I program is shown in Figure 83. This sample PL/I program makes several calls through the JNI.

Upon entry, a reference to the calling Java Object, myObject is passed into the PL/I procedure. The PL/I program will use this reference to get information from the calling object. The first piece of information is the Class of the calling object which is retrieved using the GetObjectClass JNI function. This Class value is then used by the GetFieldID JNI function to get the identity of the Java string field in the Java object that we are interested in. This Java field is further identified by providing the name of the field, myString, and the JNI field descriptor, Ljava/lang/String;, which identifies the field as a Java String field. The value of the Java string field is then retrieved using the GetObjectField JNI function. Before PL/I can use the Java string value, it must be unpacked into a form that PL/I can understand. The GetStringUTFChars JNI function is used to convert the Java string into a PL/I varyingz string which is then displayed by the PL/I program.

After displaying the retrieved Java string, the PL/I program prompts the user for a PL/I string to be used to update the string field in the calling Java object. The PL/I string value is converted to a Java string using the NewString JNI function. This new Java string is then used to update the string field in the calling Java object using the SetObjectField JNI function.

When the PL/I program ends control is returned to Java, where the newly updated Java string is displayed by the Java program.

Figure 83. PL/I Sample Program #2 - Passing a String
 *Process Limits( Extname( 100 ) ) Margins( 1, 100 ) ;
 *Process Display(Std) Dllinit Extrn(Short);
 *Process Rent Default( ASCII IEEE );
 plijava_demo: package exports(*);

  Java_passString_pliShowString:
  Proc( JNIEnv , myJObject )
    external( "Java_jPassString_pliShowString" )
    Options( FromAlien NoDescriptor ByValue );

   %include ibmzjni;

   Dcl myBool           Type jBoolean;
   Dcl myClazz          Type jClass;
   Dcl myFID            Type jFieldID;
   Dcl myJObject        Type jObject;
   Dcl myJString        Type jString;
   Dcl newJString       Type jString;
   Dcl myID             Char(9)   Varz static init( 'myString' );
   Dcl mySig            Char(18)  Varz static
                        init( 'Ljava/lang/String;' );
   Dcl pliStr           Char(132) Varz Based(pliStrPtr);
   Dcl pliReply         Char(132) Varz;
   Dcl pliStrPtr        Pointer;
   Dcl nullPtr          Pointer;

   Display('  ');

   /* Get information about the calling Class              */
   myClazz = GetObjectClass(JNIEnv, myJObject);

   /* Get Field ID for String field from Java              */
   myFID = GetFieldID(JNIEnv, myClazz, myID, mySig );

   /* Get the Java String in the string field              */
   myJString = GetObjectField(JNIEnv, myJObject, myFID );

   /* Convert the Java String to a PL/I string             */
   pliStrPtr = GetStringUTFChars(JNIEnv, myJString, myBool );

   Display('From  PLI: String retrieved from Java is: ' || pliStr );
   Display('From  PLI: Enter a string to be returned to Java:' )
          reply(pliReply);

   /* Convert the new PL/I string to a Java String         */
   newJString = NewString(JNIEnv, trim(pliReply), length(pliReply) );

   /* Change the Java String field to the new string value */
   nullPtr = SetObjectField(JNIEnv, myJObject, myFID, newJString);

  End;

 end;

Step 4: Compiling and Linking the PL/I Program

Compiling the PL/I Program

Compile the PL/I sample program with the following command:

   pli -c passString.pli
Linking the Shared Library

Link the resulting PL/I object deck into a shared library with this command:

   c89 -o libpassString.so passString.o

Be sure to include the lib prefix on the name or the PL/I shared library or the Java class loader will not find it.


Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)