This is documentation for Mathematica 5, which was
based on an earlier version of the Wolfram Language.
View current documentation (Version 11.2)

Documentation / Mathematica / Add-ons & Links / J/Link / Part 2. Writing Java Programs That Use Mathematica /

2.5 Creating Links with MathLinkFactory

To isolate clients of the J/Link classes from implementation details it is required that clients never explicitly name a link class in their code. This means that programs will never call new to create an instance of a link class. Instead, a so-called "factory method" is supplied that creates an appropriate instance for you, based on the arguments you pass in. This factory method takes the place of calling MLOpen in a C program.

The method that creates a KernelLink is a static method called createKernelLink() in the MathLinkFactory class:

public static KernelLink createKernelLink(String cmdLine) throws MathLinkException

    

public static KernelLink createKernelLink(String[] argv) throws MathLinkException

    

. . . plus a few more of limited usefulness

There are also two functions called createMathLink() that take the same arguments but create a MathLink instead of a KernelLink. Very few programmers will need to use createMathLink() because the only reason to do so is if you are connecting to a program other than the Mathematica kernel. See the JavaDoc files for a complete listing of the methods.

The second signature of createKernelLink() is convenient if you are using the command line parameters that your program was launched with, which are, of course, provided to your main() function as an array of strings. An example of this use can be found in the sample program in Section 2.4. Other times it will be convenient to specify the parameters as a single string, for example:

KernelLink ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname 'c:\\program files\\wolfram research\\mathematica\\5.0\\mathkernel'");

Note that the linkname argument is wrapped in single quotation marks ('). This is because MathLink parses this string as a complete command line, and wrapping it in single quotation marks is an easy way to force it to be seen as just a filename. Also note that it is required to type two backslashes to indicate a Windows directory separator character when you are typing a literal string in your Java code because Java, like C and Mathematica, treats the \ as a meta-character that quotes the character following.

Here are some typical arguments for createKernelLink() on various platforms when given as a single string. Note the use of quote characters (' and "):

// Typical launch on Windows

KernelLink ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname 'c:\\program files\\wolfram research\\mathematica\\math42\\mathkernel.exe'");



// Typical launch on Unix

KernelLink ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname 'math -mathlink'");



// Typical launch on Mac OS X

KernelLink ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname '\"/Applications/Mathematica 5.0.app/Contents/MacOS/MathKernel\" -mathlink'");



// Typical "listen" link on any platform:

KernelLink ml = MathLinkFactory.createKernelLink("-linkmode listen -linkname 1234 -linkprotocol tcp");



// Windows can use the default protocol for listen/connect links:

KernelLink ml = MathLinkFactory.createKernelLink("-linkmode listen -linkname foo");

Here are typical arguments for createKernelLink() when given as an array of strings:

// Typical launch on Windows:

String[] argv = {"-linkmode", "launch", "-linkname", "c:\\program files\\wolfram research\\mathematica\\5.0\\mathkernel"};



// Typical launch on UNIX:

String[] argv = {"-linkmode", "launch", "-linkname", "math -mathlink"};



// Typical launch on Mac OS X:

String[] argv = {"-linkmode", "launch", "-linkname", "\"/Applications/Mathematica 5.0.app/Contents/MacOS/MathKernel\" -mathlink"};



// Typical "listen" link on any platform:

String[] argv = {"-linkmode", "listen", "-linkname", "1234", "-linkprotocol", "tcp"};



// Windows can use the default protocol for listen/connect links:

String[] argv = {"-linkmode", "listen", "-linkname", "foo"};

The arguments for createKernelLink() and createMathLink() (e.g., -linkmode, -linkprotocol, and so on) are identical to those used for MLOpen in the MathLink C API. Consult the MathLink documentation for more information.

The createKernelLink() and createMathLink() methods will always return a non-null link object or throw a MathLinkException. You do not need to test whether the returned link is null. Because these methods throw a MathLinkException on failure, you need to wrap the call in a try block:

KernelLink ml = null;

try {

    ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname 'c:\\program files\\wolfram research\\mathematica\\5.0\\mathkernel'");

} catch (MathLinkException e) {

    // This is equivalent to MLOpen returning NULL in a C program.

    System.out.println(e.getMessage());

    System.exit(1);

}

The fact that createKernelLink() succeeds does not mean that the link is connected and functioning properly. There are a lot of things that could be wrong. For example, if you launch a program that knows nothing about MathLink, createKernelLink() will still succeed. There is a difference between creating a link (which involves setting up your side) and connecting one (which verifies that the other side is alive and well).

If a link has not been connected yet, MathLink will automatically try to connect it the first time you try to read or write something. Alternatively, you can call the connect() method to explicitly connect the link after creating it. If the link cannot be connected, then the attempt to connect, whether made explicitly by you or internally by MathLink, will fail or even hang indefinitely. It can hang because the attempt to connect will block until the connection succeeds or until it detects a fatal problem with the link. In some cases, neither will happen—for example, if you mistakenly launch a program that is not MathLink-aware. Dealing with blocking in J/Link methods is discussed more thoroughly later, but in the case of connecting the link we have an easy solution. The connect() method has a second signature that takes a long argument specifying the number of milliseconds to wait before abandoning the attempt to connect: connect(long timeoutMillis). You do not need to explicitly call connect() on a link—it will be connected for you the first time you try to read something. You can use a call to connect() to catch failures at a well-defined place, or if you want to use the automatic time out feature. Here is a code fragment that demonstrates how to implement a time out in connect().

KernelLink ml = null;

try {

    ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname 'c:\\program files\\wolfram research\\mathematica\\5.0\\mathkernel'");

} catch (MathLinkException e) {

    System.out.println("Link could not be created: " + e.getMessage());

    return; // Or whatever is appropriate.

}



try {

    connect(10000); // Wait at most 10 seconds

} catch (MathLinkException e) {

    // If the timeout expires, a MathLinkException will be thrown.

    System.out.println("Failure to connect link: " + e.getMessage());

    ml.close();

    return; // Or whatever is appropriate.

}

When you are finished with a link, call its close() method. Although the finalizer for a link object will close the link, you cannot guarantee that the finalizer will be called in a timely fashion, or even at all, so you should always manually close a link when you are done.

Using Listen and Connect Modes

You can use the listen and connect linkmodes, instead of launch, if you want to connect to an already-running program. Using listen and connect linkmodes in J/Link works in the same way as with C MathLink programs. See the MathLink Tutorial (http://www.mathsource.com/Content/Enhancements/MathLink/0206-693) or The Mathematica Book for more information.