Copyright © 2001-2002, Junzo SATO. All rights reserverd.

AddTwo: The Traditional Example

Junzo SATO

Aug 11th 2002

AddTwo is one of the most traditional examples in MathLink programming. The native function defined in the external program is called from Mathematica with two argument integers. Then it returns the sum of them back to Mathematica. In J/Link, this native function is implemented in the form of a method in a Java class.

Implementation

Writing Java Class: AddTwoLib

The most simplest definition of the class we need to implement would be as follows. The class is declared under the specified package context "JLinkProgramming.AddTwoLib". The method addTwo( ) is comming inside this class. The static method is enough for this example because the user need not to create an instance of this class.

AddTwoLib.java

package JLinkProgramming.AddTwoLib;
public class AddTwoLib {
    public static int addTwo(int i, int j) {
        return i+j;
    }
}

Although returning the sum of two integers i and j is sufficient, addTwo( ) should have more lines for error handling such as overflow. When this class AddTwoLib is loaded from Mathematica, there is a MathLink connection between J/Link and Mathematica. This means that the Java method can send the urgent message to MathKernel via this KernelLink object.

KernelLink link = StdLink.getLink();
link.message("addTwo::test", "Hello from addTwo!");

Install.getStdLink( ) returns the MathLink connection. When MathKernel received the message from the link, it evaluates Message[addTwo::test, "Hello from addTwo!"]. The addTwo::test is defined in the Mathematica package which will be described later. In a similar manner, the message addTwo::ovflw is generated when the result integer overflows.

link.message("addTwo::ovflw", (String)null);

Because the symbol $Failed is returned when the error occurres inside addTwo( ), the return type of this method becomes void instead of int. Result of the calculation is sent manually to Mathematica. The entire source code of the class AddTwoLib is as follows.

AddTwoLib.java

package JLinkProgramming.AddTwoLib;
import com.wolfram.jlink.*;
public class AddTwoLib {
    public static void addTwo( int i, int j ) {
        long sum = i + j;
        KernelLink link = StdLink.getLink();
        if (link != null) {
            // this method is called via MathLink
            link.message("addTwo::test", "Hello from addTwo!");
                        
            // check the result.
            if (i>0 && j>0 && sum<0 || i<0 && j<0 && sum>0) {
                // put ovflw message.
                link.message("addTwo::ovflw", (String)null);                
                
                // put $Failed
                link.beginManual();
                try {
                    link.putSymbol("$Failed");
                } catch (MathLinkException e) {
                    System.out.println(
                        "An exception occurred in putSymbol(): " +
                        e.getMessage()
                    );
                    return;
                }
                return;
            } else {
                // put result
                link.beginManual();
                try {
                    link.put(sum);
                } catch (MathLinkException e) {
                    System.out.println(
                        "An exception occurred in put(): " +
                        e.getMessage()
                    );
                    return;
                }
                return;
            }
        } else {
            // this method is called within Java
            return;        
        }
    }
}

Note that because parameter check for addTwo( ) is done by J/Link, we don't write any code to confirm i and j. In Java, AddTwoLib.addTwo(100000000000000000000, 1) or AddTwoLib.addTwo(1.2, 2.3) causes an exception for the reason of parameter overflow of int i or parameter type mismatch. The addTwo(float, float) is not defined. This kind of exception is detected by J/Link when the user calls the method from Mathematica.

Writing Mathematica Package: AddTwoLib.m

Definitions of message names addTwo::test and addTwo::ovflw and the usage of addTwo method can be defined in a standard Mathematica package. Although it's possible to script these definitions in Java code with KernelLink's evaluate(), using Mathematica package is more convenient. The source of the package becomes like this.

AddTwoLib.m

BeginPackage["JLinkProgramming`AddTwoLib`AddTwoLib`"]
Unprotect[Evaluate[$Context<>"*"]]

addTwo::usage="addTwo[i,j] returns the sum of two integers: i+j";
addTwo::ovflw="The resulting value overflow.";
addTwo::test="The message is ... `1`";

Begin["`Private`"]
(*nothing so far*)
End[]
(* don't protect symbols if you will add more definitions to them later.*)
(*Protect[Evaluate[$Context<>"*"]]*)
EndPackage[]

Needs["JLink`"]

Because J/Link will add definitions to the symbol addTwo when it loads the Java class, we cannot protect the symbol addTwo.

Evaluation

Loading J/Link

[Graphics:Images/AddTwo_gr_1.gif]
[Graphics:Images/AddTwo_gr_2.gif]
[Graphics:Images/AddTwo_gr_3.gif]

Messages about symbol name are ignored.

[Graphics:Images/AddTwo_gr_4.gif]

Loading Package

The Mathematica package "AddTwoLib.m" and the Java archive "AddTwoLib.jar" are installed to the following locations:
    AddOns/Applications/JLinkProgramming/AddTwoLib/AddTwoLib.m
    AddOns/Applications/JLinkProgramming/Java/AddTwoLib.jar

AddTwoLib and JLink packages are loaded.

[Graphics:Images/AddTwo_gr_5.gif]

LoadJavaClass[ ] finds Java code in the system and connection between Mathematica symbol addTwo and Java method addTwo() is established.
Because the static method addTwo() is called. Loading the Java class AddTwoLib, before using its static method, is required.

[Graphics:Images/AddTwo_gr_6.gif]
[Graphics:Images/AddTwo_gr_7.gif]

As we can see usage and  definition of the symbol addTwo, JLink`CallJava`Private`callJava[ ] is invoked when we try to evaluate addTwo from Mathematica.

[Graphics:Images/AddTwo_gr_8.gif]
[Graphics:Images/AddTwo_gr_9.gif]
[Graphics:Images/AddTwo_gr_10.gif]
[Graphics:Images/AddTwo_gr_11.gif]
[Graphics:Images/AddTwo_gr_12.gif]
[Graphics:Images/AddTwo_gr_13.gif]

The addTwo[2, 3] returns 2+3. Because the command link.message("addTwo::test", "Hello from addTwo!") is executed in Java, the message is received correctly before the result value 5 is shown.

[Graphics:Images/AddTwo_gr_14.gif]
[Graphics:Images/AddTwo_gr_15.gif]
[Graphics:Images/AddTwo_gr_16.gif]

This is the example which returns the message addTwo::ovflw and the symbol $Failed.

[Graphics:Images/AddTwo_gr_17.gif]
[Graphics:Images/AddTwo_gr_18.gif]
[Graphics:Images/AddTwo_gr_19.gif]
[Graphics:Images/AddTwo_gr_20.gif]

Here is the sample of autogenerated error message by J/Link. The first argument exceeds the max value that Java int can hold.

[Graphics:Images/AddTwo_gr_21.gif]
[Graphics:Images/AddTwo_gr_22.gif]
[Graphics:Images/AddTwo_gr_23.gif]

As we didn't define addTwo for real numbers, this will fail.

[Graphics:Images/AddTwo_gr_24.gif]
[Graphics:Images/AddTwo_gr_25.gif]
[Graphics:Images/AddTwo_gr_26.gif]

Uninstalling J/Link

J/Link environment and MathKernel are ended.

[Graphics:Images/AddTwo_gr_27.gif]
[Graphics:Images/AddTwo_gr_28.gif]
[Graphics:Images/AddTwo_gr_29.gif]


Converted by Mathematica      August 11, 2002