Calling Java

There are several ways to call Java™ code when you are generating Java from EGL. This topic covers a few of the most common ways, including using the system functions in the JavaLib system library such as javaLib.invoke(), and declaring an ExternalType part.

Prerequisites

Calling a Java class once

If you need to use a method in a Java class only once, you can use the javaLib.invoke system function.

This example calls the method random. This method belongs to the class java.lang.Math and returns a random number between 0 and 1. In this case, the class resembles an EGL library and the method works like a function in this library.

The only methods you can call in this way are the methods defined as static. "Static" is a Java term that has no parallel in EGL; in this context, it means that the method is ready to be called at any time and needs no initialization before use.

  1. In an EGL function within a logic part, declare any variables that you might need to pass or that you might need to accept a return value:
    myNumber float;
  2. Use the javaLib.invoke() system function to call the method, passing the name of the class and the method to call as parameters:
    myNumber = javaLib.invoke("java.lang.Math", "random");
  3. Then, you can use the results of the call:
    sysLib.writeStderr(strLib.formatNumber(myNumber));

To pass a parameter to the method, use the argument parameter of javaLib.invoke().

Calling a Java class multiple times

If you plan to use methods in a Java class several times, or if the method that you want to call is not defined as static, you should create an ExternalType part, as in "Creating an ExternalType part to represent a class" that follows. However, for compatibility with migrated programs, and with a little less EGL code, you can use other functions in javaLib to initialize and use a class multiple times, even its non-static methods.

The following example uses a different class that returns random numbers. The method nextInt in the class java.util.Random provides an alternate way to return a random integer. Because the method is not defined as static, you cannot use javaLib.invoke() to call nextInt without any preparation:
//Error! The method nextInt() is not static.
myInt int = javaLib.invoke("java.util.Random", "nextInt");
Instead, you must first initialize the class and give it an identifier in EGL using javaLib.storeNew(). Note the use of the casting operator, AS, to convert Java types to EGL:
javaLib.storeNew("myRandomGenerator" AS "objId:java", "java.util.Random");
Then you can use the class repeatedly through javaLib.invoke:
myInt int = javaLib.invoke("myRandomGenerator" AS "objId:java", "nextInt");

In these examples, the string myRandomGenerator is an identifier that represents the class. Each time you use the class, you tell EGL that this identifier refers not to an EGL part or a string literal but a Java class with the code AS "objId:java". For more information, see as operator. For more details on calling Java classes and methods, see Java access functions.

Creating an ExternalType part to represent a class

If you plan to use the class often, or if the method that you want to use is not defined as static, you can define an EGL ExternalType part, an EGL part that represents a Java class directly. After you have defined the ExternalType part, you can create variables based on it and use those variables just like you would use the names of EGL libraries.

This example uses the class java.util.Random. This class has a non-static method named nextInt which returns a random integer. Again, for the purposes of EGL programming, imagine that the class is a library and the methods are functions.

  1. In an EGL source file, begin defining the ExternalType part by giving it the name of the Java class you want to use.
    ExternalType Random type JavaObject
        {packageName = "java.util", 
        javaName = "Random"}
    //prototypes go here
    end
    Note that the name of the Java class is divided into two properties:
    • packageName is the name of the package that holds the class. Java packages and EGL packages work in much the same way.
    • javaName is the name of the Java class itself. You can name the ExternalType part with the same name as the class if you want to.
  2. Within the ExternalType part, create function prototypes that represent the methods in the class that you want to use:
    ExternalType Random type JavaObject
        {packageName = "java.util", 
        javaName = "Random"}
        function nextInt() returns(int);
    end
    Again, function prototypes in Java are similar to function prototypes in EGL, such as those in an Interface part. They list the function or method name, its arguments, and its return value, but have no internal logic. Here, a prototype links a function in the ExternalType part to a method in the Java class.

    Also, you must be careful to match Java types to compatible EGL types and vice versa. Tables associating EGL parts and Java parts are available in EGL primitives and Java.

  3. The ExternalType part also requires a constructor. In EGL terms, a constructor is a function that runs when a new variable that is based on the part is created. Constructors are not commonly used in EGL; for more information about them, see new operator.
    ExternalType Random type JavaObject
        {packageName = "java.util", 
        javaName = "Random"}
        function nextInt() returns(int);
        constructor();
    end
  4. To create a variable based on an ExternalType part, you must first call its constructor with the new keyword and the name of the part:
    myRandomGenerator Random = new Random();
    The code new Random() is actually a function call to the constructor() function prototype in the part definition, which in turn refers to the constructor of the Java class.
  5. Use the functions in ExternalType just like you were using an EGL library:
    myInt int = myRandomGenerator.nextInt();
    sysLib.writeStderr(strLib.formatNumber(myInt));
Here is an example of a complete program that uses an ExternalType part as explained above:
/*
Writes a random integer to the console
using an ExternalType part
*/
program ExternalTypeTest type BasicProgram

    function main()
        myRandomGenerator Random = new Random();
        myInt int = myRandomGenerator.nextInt();
        SysLib.writeStderr(StrLib.formatNumber(myInt));
    end
    
end

externalType Random type JavaObject 
    {packageName = "java.util", 
    javaName = "Random"}
    constructor();
    function nextInt() returns(int);
end

For more details on the ExternalType part, see ExternalType part.


Feedback