Mathworks supports calling and using Java objects from Matlab but not calling Matlab commands from Java. This page provides techniques to call Matlab commands from Java
The source code, documentation, support jar, and a demo jar are all available at http://matlabcontrol.googlecode.com/ "
MatlabControl.eval(String command)
is used to evaluate
MatlabControl.feval(String command, Object[] args) is used to evaluate functions as if you were executing them at the Matlab command prompt, where args is the list of arguments. If the function takes n arguments, args should be an array of size n
Object[] MatlabControl.blockingFeval(String command, Object[] args) is used to evaluate functions using feval just like MatlabControl.feval, but blockingFeval waits for the return values and passes them back to the caller as an Object[].
(If you are using Matlab R14, the JMI interface has changed and MatlabControl.java won't compile. You need to apply this patch. Many people are still using this code as of 2010, but if you are using Matlab versions later than R14 and the MatlabControl.java class does not work for you, you might consider using Options #1 or #2 above, which are much more recent. )
The following example is Java code that uses all three functions. First, instantiate a MatlabControl object
...
MatlabControl mc = new MatlabControl();
Then, evaluate a string or two using the "eval()" function
mc.eval(new String("help"));
mc.eval(new String("help(plot)"));
mc.eval(new String("x=5"));
mc.eval(new String("x=5;"));
mc.eval(new String("sqrt(x)"));
mc.eval(new String("myScript"));
Now, evaluate a few functions that takes arguments using the "feval()" function. To pass no arguments, use null.
mc.feval(new String("help"),null);
Object[] args = new Object[2];
args[0]=new String("plot");
args[1]=new String("axis");
mc.feval(new String("help"), args);
Finally, evaluate a function that gives return arguments using the "blockingFeval()" function.
args = new Object[1];
args[0]=new Double(5);
Double returnVals = (Double)mc.blockingFeval(new String("sqrt"), args);
System.out.println(returnVals.toString());
To compile MatlabControl, make sure that "MATLAB_ROOT\java\jar\jmi.jar" is in your classpath, where MATLAB_ROOT is the root installation directory of Matlab. To use the class, make sure it is in your matlab classpath. Change your matlab classpath by typing "edit classpath.txt" at the matlab prompt.
There are three things snags that people usually hit when trying to run this:
Snag 1: MatlabControl objects must be instantiated from within your Matlab session! (or by other java objects that were instantiated by your matlab session). This is because Matlab runs its own JVM, and you need to run MatlabControl in the same JVM that matlab is using. (this is why you need to make sure that MatlabControl is in your matlab classpath.) More specifically, if your program is defined in "mypackage/MyClass.java", you need to type
mypackage.MyClass.main({'param1','param2',...})
at the Matlab command prompt. If the object does not have a "main" function, you can just instantiate it but you must call the constructor manually, as follows:
obj = mypackage.MyClass
obj.MyClass(param1, param2,...)
Snag 2: Matlab is single-threaded. This means that if you try to
eval or feval from within a Java function that was called directly from a Matlab
function, it will hang waiting for the first matlab function to terminate. To
solve this problem, you must call MatlabControl functions from a new
thread! This can be any thread, as long as it is not the Matlab thread of
execution. As an example, I have created a test function that properly spawns a
new thread and calls the eval, feval, and blockingFeval functions so that the
test functions can be called directly from Matlab. Type the following into your
matlab prompt to make sure you get similar behavior:
In summary of the first two snags, this should always be the standard order of execution:
Snag 3: There is a little documentation in the MatlabControl source code that you might want to look at. Also, there are some more advanced features, including more advanced objects like MatlabEvalCommand and MatlabFevalCommand within MatlabControl. These support the use of a callback function called matlabControlcb.m that you must create, and will become useful when you realize that matlab cell arrays and such are not really converted into java objects but only their handles are converted into java objects, so you need to do all manipulation of them in matlab. When you get to that point, try looking at the souce code and experimenting.
Matlab R13 (6.5) has a timer object supported. However, I have found it really useful to use this version, which has a GUI that allows you to change the period and start, stop the timer. This is especially useful if you are using an older version of Matlab. You can also replace the timer.jar file that came with matlab with this one, which is the same as the normal matlab timer but adds a gui interface to each one that you instantiate.
The main advantage to using timer objects is that you can wait by using a timer instead of using the matlab "wait" command. The "wait" command basically does a spinning wait, so matlab cannot run any other commands. This is a problem if you have a java object that is trying to run a matlab command. It is useful in general for event-based programming in matlab, which you might be doing if you are using matlab to interact with anything, like Java apps or the real world via the serial port.
There is a lot more info on my help page pertaining to the TinyOS project at UC Berkeley that you will probably find useful after you filter out some of the tinyos help stuff. Look especially at the end of the page and follow some of those links for good clues..
A lot of people (including myself) have been trying to figure out how to call Matlab commands from Java but Mathworks has not wanted to support it or even give out much information, as people on the newsgroups (also) know. The most information they release is in the following URL and email.
If you want to know more about using Matlab from Java, however, look at the files in the .jar files in the matlab\java\jar directory. You can use introspection to find out what methods the classes have, etc. For example, you can type methodsview com.mathworks.jmi.Matlab at your Matlab command prompt to see the Matlab class (which is the one I used for MatlabCommand.java). This class also has functions such as mtGet() and mtSet() that I believe allow you to read and write to the Matlab workspace from Java. It also has versions of eval and feval that return the return values of your matlab commands back to your Java object.
Of course, sometimes the function signatures aren't enough to figure out how to use them. You might consider using Gnu JODE to decompile the .class files back into .java files (but this might go against some license agreement).
If you want to know more about using Java from Matlab (a feature which IS supported by mathworks) read the matlab documentation on "Java/Matlab Interface".
July 21, 2010 -- In addition to the folks mentioned above who contributed new software packages, thanks to Tomasz Kowalski for finding a synchronization bug in MatlabControl.java!
Copyright © 2002 Kamin Whitehouse