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 evaluatestrings as if you were executing them at the Matlab command prompt. These can be matlab scripts, commands, or functions that take no arguments.**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:

>> mc=MatlabControl;

>> mc.testEval('x = 5')

x =

5

>> mc.testFeval('help',{'sqrt'})

SQRT Square root.

SQRT(X) is the square root of the elements of X. Complex

results are produced if X is not positive.

See also SQRTM.

Overloaded methods

help sym/sqrt.m

>> mc.testBlockingFeval('sqrt',{x})

2.2361

In summary of the first two snags, this should always be the standard order of execution:

- instantiate Java object from within Matlab
- spawn new thread in Java
- call Matlab functions from new Java thread

**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