Wolfram ResearchPRODUCTSPURCHASEFOR USERSCOMPANYOUR SITES
THIS IS DOCUMENTATION FOR AN OBSOLETE PRODUCT.
SEE THE DOCUMENTATION CENTER FOR THE LATEST INFORMATION.

Documentation / Mathematica / Add-ons & Links / J/Link / Part 2. Writing Java Programs That Use Mathematica / Sending Computations and Reading Results /

2.8.4 Reading the Result

Before we dive into reading expressions from a link, keep in mind that if you just want the result back as a string or an image, then you are better off using one of the "evaluateTo" methods described in the next section. These methods send a computation and return the answer as a string or image, so you do not have to read it off the link yourself. Also, if you are not interested in the result, you will use discardAnswer() and thus not have to bother reading it.

J/Link provides a number of methods for reading expressions from a link. Many of these methods are essentially identical to functions in the MathLink C API, so to some extent you can learn how to use them by reading standard MathLink documentation. You should also consult the J/Link JavaDoc files for more information. The reading methods generally begin with "get." Examples are getInteger(), getString(), getFunction(), and getDoubleArray2(). There are also two type-testing methods that will tell you the type of the next thing waiting to be read off the link. These methods are getType() and getNext().

As stated earlier, one method you will generally not call is nextPacket(). When waitForAnswer() returns, nextPacket() has already been called internally on the ReturnPacket that holds the answer, so this final packet has already been "opened" and you can start reading its contents right away.

The vast majority of MathLinkExceptions in J/Link programs are caused by trying to read the incoming expression in a manner that is not appropriate for its type. A typical example is calling a Mathematica function that you expect to return an integer, but you call it with incorrect arguments and therefore it returns unevaluated. You call getInteger() to read an integer, but what is waiting on the link is a function like foo[badArgument]. There are several general ways for dealing with problems like this. The first technique is to avoid the exception by using getNext() to determine the type of the expression waiting. For example:

ml.evaluate("SomeFunction[]");

ml.waitForAnswer();

int result;

int type = ml.getNext();

if (type == MathLink.MLTKINT) {

    result = ml.getInteger();

} else {

    // What you do here is up to you.

    System.out.println("Unexpected result: " + ml.getExpr().toString());

    // Throw away the packet contents.

    ml.newPacket();

}

A related technique is to read the result as an Expr and examine it using the Expr methods. The Expr class is discussed in Section 2.14.

ml.evaluate("SomeFunction[]");

ml.waitForAnswer();

int result;

Expr e = ml.getExpr();

if (e.integerQ()) {

    result = e.asInt();

} else {

    // What you do here is up to you.

    System.out.println("Unexpected result: " + e.toString());

}

A final technique is to just go ahead and read the expression in the form that you expect, but catch and handle any MathLinkException. (Remember that the entire code fragment below must be wrapped in a try/catch block for MathLinkExceptions, but we are only seeing an inner try/catch block for MathLinkExceptions known to be thrown during the read.)

ml.evaluate("SomeFunction[]");

ml.waitForAnswer();

int result;

try {

    result = ml.getInteger();

} catch (MathLinkException e) {

    ml.clearError();

    System.out.println("Unexpected result: " + ml.getExpr().toString());

    ml.newPacket(); // Not strictly necessary because of the getExpr() above

}

Another tip for avoiding bugs in code that reads from a link is to use the newPacket() method liberally. A second very common cause of MathLinkExceptions is forgetting to read the entire contents of a packet before going on to the next computation. The newPacket() method causes the currently opened packet to be discarded. Another way of saying this is that it throws away all unread parts of the expression that is currently being read. It is a clean-up method that ensures that there are no remnants left over from the last packet when you go on to the next evaluation. Consider the following code:

ml.evaluate("SomeFunction[]");

ml.waitForAnswer();

int result;

try {

    result = ml.getInteger();

} catch (MathLinkException e) {

    ml.clearError();

    System.out.println("Unexpected result");

    // Oops. Forgot to call newPacket() to throw away the contents.

}



// Boom. The next line causes a MathLinkException if the previous getInteger()

// call failed, because nextPacket() will be called before the previous packet

// was emptied.

ml.evaluate("
AnotherFunction[]");

ml.discardAnswer();

This code will cause a MathLinkException to be thrown at the indicated point if the previous call to getInteger() had failed because the programmer forgot to either finish reading the result or call newPacket(). Here is an even simpler example of this error:

ml.evaluate("SomeFunction[]");

ml.waitForAnswer();

// Oops. Forgot to read or throw away the result.

// Probably meant to call discardAnswer() instead of

// waitForAnswer().



ml.evaluate("
AnotherFunction[]");

ml.discardAnswer(); // MathLinkException here!



Any questions about topics on this page? Click here to get an individual response.Buy NowMore Information


 © 2008 Wolfram Research, Inc.  Terms of Use  Privacy Policy | [ja] |
Sign up for our newsletter: