************************************* * * * DB/C Newsletter * * April 1998 * * * ************************************* News and Comments DB/C JX and DB/C FS beta testing continues. Hopefully, we will have some announcements about these products in the next newsletter. Several beta testers of DB/C JX are attempting to integrate existing DB/C programs with new Java application systems. The integration entails using one of the DB/C JX to Java interface mechanisms. In this newsletter, we describe a generalized interface between DB/C JX and Java that allows DB/C JX programs to call any Java class directly without having to write any Java code at all. don.wills@swc.com ***************************************************************************** Calling Java APIs Without Writing Any Java DB/C JX provides the ability to call Java programs directly from DB/C. This is done either with the JCALL statement or with user defined verbs. The interface is fairly straightforward. It is described in Chapter 8 of the DB/C JX manual. Although a DB/C JX program can call Java methods, it can't directly call any of the various standard Java APIs without some special Java interface code. The reason is that the parameters that are specified in the JCALL and user verb statements are DB/C variables (e.g. DIM and FORM), whereas the parameters for calling Java methods in typical Java APIs are Java primitive types (e.g. int, long and boolean) and Java object references (e.g. String and BigDecimal). To make the translation, a layer of Java code is needed to move data from DB/C variables to Java variables and back. A layer of Java code can be specially created for each of the various Java API classes. This would be quite time consuming as there are hundreds of classes and thousands of methods in the standard Java API. So instead of special code for each Java class, we have created a generalized layer of Java code that provides the translation of parameters for any Java class. This Java code uses the JCALL interface of DB/C JX. This project began as an example of a DB/C JX program calling a Java API. In this case, the program was a FTP client program written in DB/C. The Java API classes that it uses are several TCP/IP support classes that are found in the java.net package. The example program is FTP.PRG. It can be found on the ftp.swc.com server in the /pub/misc/jxsample/ftp directory. This program is adapted from the DB/C 9 version of the same program which was described in the June 1995 DB/C Newsletter. A few changes were made to the original program. Most importantly, notice the JCALL statements that call the Java TCP/IP API. They are found in the last 200 lines of the DB/C JX version of FTP.PRG. The generalized Java interface code is jcall.java. It can be found in the /pub/misc/jxsample/jcall directory on the same server. There are eight different types of calls that are handled by the generalized DB/C-to-Java JCALL interface. These calls are: 1. Creating a Java object and calling the constructor 2. Calling an instance method of a Java class 3. Calling a static method of a Java class 4. Retrieving an Exception 5. Setting the value of an instance field 6. Getting the value of an instance field 7. Setting the value of a static field 8. Getting the value of a static field Here is the syntax for each of these calls: 1. Creating an object and calling the constructor JCALL <'new ' class>, , 2. Calling an instance method JCALL , , , 3. Calling a static method JCALL , , 4. Retrieving an Exception JCALL "get Exception", 5. Get the value of an instance field JCALL <'get ' field>, , 6. Set the value of an instance field JCALL <'set ' field>, , 7. Get the value of a static field JCALL <'get ' class and field>, 8. Set the value of a static field JCALL <'set ' class and field>, The first operand of each JCALL statement is a CHAR variable or a literal. The 'new ', 'get ' and 'set ' elements are actually those string values. The element is a Java method name. The <... field> element is a Java field (class variable) name. The element is a fully qualified class name followed by a period followed by a method name. The <... class and field> element is a fully qualified class name followed by a period followed by a field name. The element is an OBJECT variable. The element is an OBJECT or CHAR variable. The element is a CHAR, FORM, INT, FLOAT or OBJECT variable. The element is a CHAR, FORM, INT, FLOAT or OBJECT variable or literal. The element is a comma delimited list of zero or more s. If a JCALL statement causes an exception, the OVER flag is set. Otherwise the OVER flag is cleared. The "get Exception" JCALL statement can be used to retrieve the Exception. The remainder of this article shows examples of the use of the JCALL statement. This example creates a String with the value "Hello World!" and stores its reference in the DB/C object variable S1. S1 OBJECT JCALL "new java.lang.String", S1, "Hello World!" The next example assumes that S1 refers to a String. It stores the index of the exclamation point in the S1 String into the DB/C variable N1. S1 OBJECT N1 INT 8 JCALL "indexOf", S1, N1, "!" The next example uses the static method valueOf in the String class to create a String object with value "321", storing the actual value "321" in C1. In this situation, there are several versions of valueOf. The JCALL interface code will select the appropriate method based on the parameters specified in the DB/C parameter list. In this case, String valueOf(int i) will be chosen. C1 CHAR 5 N1 INT 5 MOVE 321 TO N1 JCALL "java.lang.String.valueOf", C1, N1 The previous example illustrates the JCALL interface code special handling for String and StringBuffer objects. If the destination for a String or a StringBuffer is a DB/C object variable, then a reference to the object will be stored. If the destination is a character variable, then the string value will moved to the character variable and the formpointer and length- pointer will be set accordingly. The next example retrieves an Exception. O1 OBJECT E1 OBJECT S1 CHAR 80 JCALL "new badclass", O1 IF OVER JCALL "get Exception", E1 JCALL "toString", E1, S1 DISPLAY "Exception: ", S1, *W STOP ENDIF If the program only needs the Exception message in a character variable, then the code can be written like the next example. O1 OBJECT S1 CHAR 80 JCALL "new badclass", O1 IF OVER JCALL "get Exception", S1 DISPLAY "Exception: ", S1, *W STOP ENDIF The final example shows how to use the get static field JCALL statement to display a message on the Java console. OUT OBJECT JCALL "get java.lang.System.out", OUT JCALL "println", OUT, "Hello console!" ***************************************************************************** DB/C Class Schedule Class: DB/C Language Fundamentals Date: June 3-5, 1998 (tentative) Location: Oak Brook, IL For information, contact Judi Tamkevic at: voice 630.572.0240 fax 630.572.0390 email dbc@swc.com ***************************************************************************** Subscribing to the DB/C Newsletter If you don't already have the DB/C Newsletter delivered to your email address and would like to have it emailed to you when it is produced, just send an email message to 'request@swc.com' and put the line 'subscribe dbcnews' in the body of the email message (omit the ' characters). The newsletter will be delivered to the email address from which the message was sent. To stop delivery, put the line 'unsubscribe dbcnews' in the body of the message.