This is a really bizarre application, so bear with me. The primary application consists of a Matlab back-end with a UI written in Java Swing. To launch the application, you do something like the following from the command-line:
matlab -r "initMatlab;runJavaUI;"
Assume that initMatlab
and runJavaUI
are both Matlab functions on the path of the matlab runtime that gets spawned as a result of that command. This basically spawns an instance of matlab, then runs those two matlab functions immediately after matlab starts. The weird thing is, this command-line option doesn't work on all OSes. Furthermore, not all versions of Matlab are compatible with all versions of Java (our customer wants to use REALLY old Matlab installs... can't make 'em change it).
So ... we provide a Java executable Jar that automatically generates the command line arguments based on which OS you're running in - the user just double-clicks it to bring up a small UI, then is presented with a few options. I'll call this jar the Launcher. This Launcher detects all installed instances of Java and Matlab and allows the user to pick which combination of Java and Matlab will get used. The jar uses ProcessBuilder
to launch the matlab command, which works fine, save for one thing. In Windows, the Launcher starts Matlab just fine, we see the Matlab console appear, then the Java UI appears as it should. However, on a Mac running Mountain Lion (10.8, I believe), the Matlab console never appears - this isn't to say that Matlab isn't running though - I can still make Matlab calls from the Java UI. This doesn't prevent the user from using the UI, but sometimes Matlab will dump error messages to the console which is problematic, because on a Mac, the user will never know when something is going wrong. The weirdest thing is, I have tried printing out the generated command line, which doesn't spawn the Matlab console when launched via ProcessBuilder
, but does spawn the Matlab console when launched via terminal. Once again, Matlab isn't failing to start, it's failing to make its own UI visible.
I have tried copying all of the Launcher's environment variables into the ProcessBuilder
prior to launching Matlab, to no avail. So I have to leave this a bit open-ended, but has anyone tried running Matlab using ProcessBuilder
, and if so, what did you do to get the Matlab console to appear on Mac OS Mountain Lion?
SSCCE
Export this code into a runnable jar file, then run the following on Mac OS Mountain Lion:
java -jar launch-matlab.jar /absolute/path/to/matlab
You should see the Matlab icon appear in the dock, but you won't be able to make the Matlab console window visible. If you run this in Windows, the Matlab console appears as it should.
public class LaunchMatlab {
public static void main(String[] args) throws Exception{
String matlabExe = "matlab";
if(args != null && args.length > 0) matlabExe = args[0];
ProcessBuilder pb = new ProcessBuilder();
pb.command(matlabExe,"-wait");
pb.environment().putAll(System.getenv());
System.err.println("Launching Matlab using following PB args: "+
pb.command());
Process p = pb.start();
System.err.println("Waiting for Matlab to exit ...");
p.waitFor();
System.err.println("Matlab exited, launcher exiting ...");
}
}
You need to specify that MATLAB is to run with a visible UI by making use of the -desktop
flag. I don't believe this is documented.
So the command you need to run is
matlab -desktop -r "initMatlab;runJavaUI;"
I've created a Java library called matlabcontrol that can abstract all of this away from you. It can launch MATLAB while running on Windows, OS X, and Linux and then allow you to interact with MATLAB via eval and feval commands. matlabcontrol's code to launch MATLAB is located in matlabcontrol.RemoteMatlabProxyFactory's createProcess(...)
method. If you make use of matlabcontrol as a Java library you won't directly interact with either this class or this method.