Byzantine Reality

Searching for Byzantine failures in the world around us

HOWTO: Call Matlab From Java {Kinda}

Looking over some of the reports on my blog reveal that pretty much everyone to this point looking at this blog look at the Java / Matlab post and not much else. Therefore, here’s everything I’ve learned concretely on how to call Matlab from Java and what NOT to do to save you some grief:

What I did:
Make a file that contains all the commands you want to run when MATLAB starts. My script file looks like this (named scriptName):

cd /directoryWithMATLABScript/
myMATLABScript
quit

The Java code I have used is a modified version of the code here. Now, use the following Java code to call MATLAB with the commands from your script:

UPDATE (07/25): Appending to the output and error Strings in the method provided is ok for MATLAB scripts with small amounts of output. On scripts that produce large amounts of output, constantly reallocating memory to new Strings and copying over the old contents of output takes an unnecessarily long amount of time. Use a StringBuffer and its append method instead.

public static String runScript(File scriptName) {
String output = “”, error = “”;
try {
String commandToRun = “/Applications/MATLAB73/bin/matlab -nodisplay < ” + scriptName;
System.out.println(commandToRun);
Process p = Runtime.getRuntime().exec(commandToRun);

String s;

BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));

BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));

// read the output from the command
System.out.println(“\nHere is the standard output of the command:\n”);
while ((s = stdInput.readLine()) != null) {
output += s + “\n”;
System.out.println(s);
}

// read any errors from the attempted command
System.out.println(“\nHere is the standard error of the command (if any):\n”);
while ((s = stdError.readLine()) != null) {
error += s + “\n”;
System.out.println(s);
}

} catch (Exception e) {
System.out.println(“exception happened – here’s what I know: “);
e.printStackTrace();
System.exit(-1);
}
return output + error;
}

This method will run MATLAB, pipe in the commands from the script file, and capture the standard output and standard error into Strings, and return that. Feel free to modify this code to play with the output or errors you’re getting from MATLAB. You can also use a DataOutputStream to push data back into MATLAB; if you’re interested in that, this link pretty much summarizes it up (third post down).

It is important to use the “-nodisplay” flag when calling MATLAB, otherwise the MATLAB GUI / IDE will open and the contents of the script won’t be called. Be sure to read about the caveats of this method below! If this was helpful, drop a comment off and let me know!

What NOT to DO / Things to keep in mind:

  1. The Matlab site gives an example of using the JAR that comes with the Matlab installation to call Java from Matlab. This requires you to start up MATLAB first, then call your Java program from it, which is the exact OPPOSITE of what you need to do. Furthermore, there is ZERO documentation on this JAR, so if there was a way to do it, nobody seems to know (at least based from multiple Google searches).
  2. The Java documentation on the Process class gives many warnings about what types of programs you should not make it call. Make sure your MATLAB program is not one of them or you may get unreliable results.
  3. I had to remove all user interaction from my MATLAB scripts to get my code “functional”, but if you fiddle with the Output and Input Streams, you may be able to work around this.
  4. You COULD just have the Runtime method execute “matlab -r matlabScriptName” and it will start up MATLAB and run “matlabScriptName.m”, but once it’s done it will idle and never quit. Technically this works, but you’ll need a way to kill the MATLAB process cleanly, as hoping Java will do it for you orphans some of MATLAB’s helper programs.
  5. Newer versions of MATLAB come bundled with a Matlab to C compiler appropriately called “MCC”, located in the “bin” directory of your MATLAB installation. You COULD use it to compile Matlab code into C code and then just run the C code from Java, but it’s not supported on Mac OS X, so it doesn’t work for me, and Google searches on the net show that many others have had problems with it. Furthermore, it doesn’t look like it pulls in the needed dependencies for all your files, so it’s not obvious if it’ll work as a standalone file. Spending several hours trying to fix the MCC so that it would work on Mac OS X proved futile, as there ended up being other problems with the C linker…

Hopefully this saves any of you some of the time it took me figuring this out.