Java access (system words)
This page includes the following sections:
Before reviewing this page, see Java access functions.
List of functions
The Java access functions are listed in the next table.
Function Description sysLib.java Invokes a method on a Java object or class and may return a value sysLib.javaGetField Returns the value of a specified field of a specified object or class sysLib.javaIsNull Returns a value (1 for true, 0 for false) to indicate whether a specified identifier refers to a null object sysLib.javaIsObjID Returns a value (1 for true, 0 for false) to indicate whether a specified identifier is in the object space sysLib.javaRemove Removes the specified identifier from the object space and, if no other identifiers refer to the object, removes the object sysLib.javaRemoveAll Removes all identifiers and objects from the object space sysLib.javaSetField Sets the value of a field in a Java object or class sysLib.javaStore Invokes a method and places the returned object (or null) into the object space, along with a specified identifier sysLib.javaStoreCopy Creates a new identifier based on another in the object space, so that both refer to the same object sysLib.javaStoreField Places the value of a class field or object field into the object space sysLib.javaStoreNew Invokes the constructor of a class and places the new object into the object space sysLib.javaType Returns the fully qualified name of the class of an object in the object space Mappings of EGL and Java types
Each of the arguments you pass to a method (and each value that you assign to a field) is mapped to a Java object or primitive type. Items of EGL primitive type CHAR, for example, are passed as objects of the Java String class. A cast operator is provided for situations in which the mapping of EGL types to Java types is not sufficient.
When you specify a Java name, EGL strips single- and double-byte blanks from the beginning and end of the value, which is case sensitive. The truncation precedes any cast. This rule applies to string literals and to items of type CHAR, DBCHAR, MBCHAR, or UNICODE. No such truncation occurs when you specify either a method argument or field value (for example, the string " my data " is passed to a method as is), unless you cast the value to objID or null.
The next table describes all the valid mappings.
Category of Argument Examples Java Type A string literal or an item of type CHAR, DBCHAR, MBCHAR, or UNICODE No cast "myString"java.lang.String Cast with objId, which indicates an identifier (objId)"myId" x = "myId"; (objId)XThe class of the object to which the identifier refers Cast with null, as may be appropriate to provide a null reference to a fully qualified class (null)"java. lang.Thread" x = "java.util. HashMap"; (null)xThe specified class Note: You can't pass in a null-casted array such as (null)"int[]"
Cast with char, which means that the first character of the value is passed (each example in the next column passes an "a") (char)"abc" X = "abc"; (char)Xchar An item of type FLOAT or a floating point literal No cast myFloatValuedouble An item of type HEX No cast myHexValuebyte array An item of type SMALLFLOAT No cast mySmallFloatfloat An item of type DATE No cast myDatejava.sql.Date An item of type TIME No cast myTimejava.sql.Time An item of type TIMESTAMP No cast myTimeStampjava.sql.Timestamp An item of type INTERVAL No cast myIntervaljava.lang.String Floating point literal No cast -6.5231E96 double Numeric item (or non-floating-point literal) that does not contain decimals; leading zeros are included in the number of digits for a literal No cast, 1-4 digits 0100short No cast, 5–9 digits 00100int No cast, 9-18 digits 1234567890long No cast, >18 digits 1234567890123456789java.math.BigInteger Numeric item Numeric item (or non-floating-point literal) that contains decimals; leading and trailing zeros are included in the number of digits for a literal No cast, 1–6 digits 3.14159float No cast, 7-18 digits 3.14159265double No cast, >18 digits 56789543.222java.math.BigDecimal Numeric item or non-floating-point literal, with or without decimals Cast with bigdecimal, biginteger, byte, double, float, short, int, long X = 42; (byte)X (long)XThe specified primitive type; but if the value is out of range for that type, loss of precision occurs and the sign may change Cast with boolean, which means that non-zero is true, zero is false X = 1; (boolean)Xboolean Note: To avoid losing precision, use an EGL float item for a Java double, and an EGL smallfloat item for a Java float. Using one of the other EGL types will probably result in a value being rounded.
For details on the internal format of items in EGL, see the help pages on Primitive types.
Examples
This section gives examples on how to use Java access functions.
Printing a date string
The following example prints a date string:
// call the constructor of the Java Date class and // assign the new object to the identifier "date". sysLib.javaStoreNew( (objId)"date", "java.util.Date" ); // call the toString method of the new Date object // and assign the output (today's date) to the chaItem. // In the absence of the cast (objId), "date" // refers to a class rather than an object. charItem = sysLib.java( (objId)"date", "toString" ); // assign the standard output stream of the // Java System class to the identifier "systemOut". sysLib.javaStoreField( (objId)"systemOut", "java.lang.System", "out" ); // call the println method of the output // stream and print today's date. sysLib.java( (objID)"systemOut","println",charItem ); // The use of "java.lang.System.out" as the first // argument in the previous line would not have been // valid, as the argument must either be a // an identifier already in the object space or a class // name. The argument cannot refer to a static field.Testing a system property
The following example retrieves a system property and tests for the absence of a value:
// assign the name of an identifier to an item of type CHAR valueID = "osNameProperty" // place the value of property os.name into the // object space, and relate that value (a Java String) // to the identifier osNameProperty sysLib.javaStore((objId)valueId, "java.lang.System", "getProperty", "os.name"); // test whether the property value is non-existent // and process accordingly myNullFlag = sysLib.javaIsNull( (objId)valueId ); if( myNullFlag = 1 ) error = 27; endWorking with arrays
When you work with Java arrays in EGL, use the Java class java.lang.reflect.Array, as shown in later examples and as described in the Java API documentation. You cannot use sysLib.javaStoreNew to create a Java array because Java arrays have no constructors.
You use the static method newInstance of java.lang.reflect.Array to create the array in the object space. After you create the array, you use other methods in that class to access the elements.
The method newInstance expects two arguments:
- A Class object that determines the type of array being created
- A number that specifies how many elements are in the array
The code that identifies the Class object varies according to whether you are creating an array of objects or an array of primitives. The subsequent code that interacts with the array also varies on the same basis.
Working with an array of objects
The following example shows how to create a 5-element object array that is accessible by use of the identifier "myArray":
// Get a reference to the class, for use with newInstance sysLib.javaStore( (objId)"objectClass", "java.lang.Class", "forName", "java.lang.Object" ); // Create the array in the object space sysLib.javaStore( (objId)"myArray", "java.lang.reflect.Array", "newInstance", (objId)"objectClass", 5 );If you want to create an array that holds a different type of object, change the class name that is passed to the first invocation of sysLib.javaStore. To create an array of String objects, for example, pass "java.lang.String" instead of "java.lang.Object".
To access an element of an object array, use the get and set methods of java.lang.reflect.Array. In the following example, i and length are numeric items:
length = sysLib.java( "java.lang.reflect.Array", "getLength", (objId)"myArray" ); i = 0; while ( i < length ) sysLib.javaStore( (objId)"element", "java.lang.reflect.Array", "get", (objId)"myArray", i ); // Here, process the element as appropriate sysLib.java( "java.lang.reflect.Array", "set", (objId)"myArray", i, (objId)"element" ); i = i + 1; endThe previous example is equivalent to the following Java code:
int length = myArray.length; for ( int i = 0; i < length; i++ ) { Object element = myArray[i]; // Here, process the element as appropriate myArray[i] = element; }Working with an array of Java primitives
To create an array that stores a Java primitive rather than an object, use a different mechanism in the steps that precede the use of java.lang.reflect.Array. In particular, obtain the Class argument to newInstance by accessing the static field TYPE of a primitive type class.
The following example creates myArray2, which is a 30-element array of integers:
// Get a reference to the class, for use with newInstance sysLib.javaStoreField( (objId)"intClass", "java.lang.Integer", "TYPE"); // Create the array in the object space sysLib.javaStore( (objId)"myArray2", "java.lang.reflect.Array", "newInstance", (objId)"intClass", 30 );If you want to create an array that holds a different type of primitive, change the Class name that is passed to the invocation of sysLib.javaStoreField. To create an array of characters, for example, pass "java.lang.Character" instead of "java.lang.Integer".
To access an element of an array of primitives, use the java.lang.reflect.Array methods that are specific to a primitive type. Such methods include getInt, setInt, getFloat, setFloat, and so forth. In the following example, length, element, and i are numeric items:
length = sysLib.java( "java.lang.reflect.Array", "getLength", (objId)"myArray2" ); i = 0; while ( i < length ) element = sysLib.java( "java.lang.reflect.Array", "getDouble", (objId)"myArray2", i ); // Here, process an element as appropriate sysLib.java( "java.lang.reflect.Array", "setDouble", (objId)"myArray2", i, element ); i = i + 1; endThe previous example is equivalent to the following Java code:
int length = myArray2.length; for ( int i = 0; i < length; i++ ) { double element = myArray2[i]; // Here, process an element as appropriate myArray2[i] = element; }Working with collections
To iterate over a collection that is referenced by a variable called list, a Java program does as follows:
Iterator contents = list.iterator(); while( contents.hasNext() ) { Object myObject = contents.next(); // Process myObject }Assume that hasNext is a numeric data and that your program related a collection to an identifier called list. The following EGL code is then equivalent to the Java code described earlier:
sysLib.javaStore( (objId)"contents", (objId)"list", "iterator" ); hasNext = sysLib.java( (objId)"contents", "hasNext" ); while ( hasNext = 1 ) sysLib.javaStore( (objId)"myObject", (objId)"contents", "next"); // Process myObject hasNext = sysLib.java( (objId)"contents", "hasNext" ); endConverting an array to a collection
To create a collection from an array of objects, use the asList method of java.util.Arrays, as shown in the following example:
// Create a collection from array myArray // and relate that collection to the identifier "list sysLib.javaStore( (objId)"list", "java.util.Arrays", "asList", (objId)"myArray" );Next, iterate over list, as shown in the preceding section.
The transfer of an array to a collection works only with an array of objects, not with an array of Java primitives. Be careful not to confuse java.util.Arrays with java.lang.reflect.Array.
Error handling
Many of the Java access functions are associated with error codes, as described in the function-specific help pages. If the value of the system variable sysVar.handleSysLibErrors is 1 when one of the listed errors occurs, EGL sets the system variable sysVar.errorCode to a non-zero value. If the value of sysVar.handleSysLibErrors is 0 when one of the errors occurs, the program ends.
Of particular interest is the sysVar.errorCode value "00001000", which indicates that an exception was thrown by an invoked method or as a result of a class initialization.
When an exception is thrown, EGL stores it in the object space. If another exception occurs, the second exception takes the place of the first. You can use the identifier caughtException to access the last exception that occurred.
In an unusual situation, an invoked method throws not an exception but an error such as OutOfMemoryError or StackOverflowError. In such a case, the program ends regardless of the value of system variable sysVar.handleSysLibErrors.
The following Java code shows how a Java program can have multiple catch blocks to handle different kinds of exceptions. This code tries to create a FileOutputStream object. A failure causes the code to set an errorType variable and to store the exception that was thrown.
int errorType = 0; Exception ex = null; try { java.io.FileOutputStream fOut = new java.io.FileOutputStream( "out.txt" ); } catch ( java.io.IOException iox ) { errorType = 1; ex = iox; } catch ( java.lang.SecurityException sx ) { errorType = 2; ex = sx; }The following EGL code is equivalent to the previous Java code:
handleSysLibErrors = 1; errorType = 0; sysLib.javaStoreNew( (objId)"fOut", "java.io.FileOutputStream", "out.txt" ); if ( sysVar.errorCode = "00001000" ) exType = sysLib.javaType( (objId)"caughtException" ); if ( exType = "java.io.IOException" ) errorType = 1; sysLib.javaStoreCopy( (objId)"caughtException", (objId)"ex" ); else if ( exType = "java.lang.SecurityException" ) errorType = 2; sysLib.javaStoreCopy( (objId)"caughtException", (objId)"ex" ); end end end
Related concepts
Java access functions
Related reference
Exception handling
Primitive types
sysLib.java
sysLib.javaGetField
sysLib.javaIsNull
sysLib.javaIsObjID
sysLib.javaRemove
sysLib.javaRemoveAll
sysLib.javaSetField
sysLib.javaStore
sysLib.javaStoreCopy
sysLib.javaStoreField
sysLib.javaStoreNew
sysLib.javaType