Main Content

Invoke MATLAB Functions Dynamically

To dynamically invoke functions on an MATLAB® Production Server™ instance, you use a reflection-based proxy to construct the MATLAB function request. The function name and all of the inputs and outputs are passed as parameters to the method invoking the request. This means that you do not need to recompile your application every time you add a function to a deployed archive.

To dynamically invoke a MATLAB function:

  1. Instantiate an instance of the MWHttpClient class.

  2. Create a reflection-based proxy object using one of the createComponentProxy() methods of the client connection.

  3. Invoke the function using one of the invoke() methods of the reflection-based proxy.

Create a Proxy for Dynamic Invocation

A reflection-based proxy implements the MWInvokable interface and provides methods that enables you to directly invoke any MATLAB function in a deployable archive. As with the interface-based proxy, the reflection-based proxy is created from the client connection object. The MWHttpClient class has two methods for creating a reflection-based proxy:

  • MWInvokable createComponentProxy(URL archiveURL) creates a proxy that uses standard MATLAB data types.

  • MWInvokable createComponentProxy(URL archiveURL, MWMarshalingRules marshalingRules) creates a proxy that uses structures.

To create a reflection-based proxy for invoking functions in the archive myMagic hosted on your local computer:

MWClient myClient = new MWHttpClient();

URL archiveURL = new URL("http://localhost:9910/myMagic");
MWInvokable myProxy =  myClient.createComponentProxy(archiveURL);

Invoke a MATLAB Function Dynamically

A reflection-based proxy has three methods for invoking functions on a server:

  • Object[] invoke(final String functionName, final int nargout, final Class<T> targetType, final Object... inputs) invokes a function that returns nargout values.

  • <T> T invoke(final String functionName, final Class<T> targetType, final Object... inputs) invokes a functions that returns a single value.

  • invokeVoid(final String functionName, final Object... inputs) invokes a function that returns no values.

All methods map to the MATLAB function as follows:

  • First argument is the function name

  • Middle set of arguments, nargout and targetType, represent the return values of the function

  • Last arguments are the function inputs

Return Multiple Outputs

The MATLAB function myLimits returns two values.

function [myMin,myMax] = myLimits(myRange)
 myMin = min(myRange);
 myMax = max(myRange);
end

To invoke myLimits from a Java® client, use the invoke() method that takes the number of return arguments:

double[] myRange = new double[]{2,5,7,100,0.5};
try
{
  Object[] myLimits = myProxy.invoke("myLimits",
                                     2,
                                     Object[].class, 
                                     myRange);
  double myMin = ((Double) myLimits[0]).doubleValue(); 
  double myMax = ((Double) myLimits[1]).doubleValue();
  System.out.printf("min: %f max: %f",myMin,myMax);
}
catch (Throwable e)
{
  e.printStackTrace();
}

Because Java cannot determine the proper types for each of the returned values, this form of invoke always returns Object[] and always takes Object[].class as the target type. You must cast the returned values into the proper types.

Return a Single Output

The MATLAB function addmatrix returns a single value.

function a = addmatrix(a1, a2)
a = a1 + a2;

To invoke addmatrix from a Java client, use the invoke() method that does not take the number of return arguments:

double[][] a1={{1,2,3},{3,2,1}};
double[][] a2={{4,5,6},{6,5,4}};
try
{
  Double[][] result = myProxy.invoke("addmatrix", 
                                     Double[][].class, 
                                     a1, 
                                     a2);

  for(Double[] row : result)
  {
    for(double element : row)
    {
      System.out.print(element + " ");
    }
  }
} catch (Throwable e)
{
  e.printStackTrace();
}

Return No Outputs

The MATLAB function foo does not return value.

function foo(a1)
min(a1);

To invoke foo from a Java client, use the invokeVoid() method:

double[][] a={{1,2,3},{3,2,1}};
try
{
  myProxy.invokeVoid("foo", (Object)a);
}
catch (Throwable e)
{
  e.printStackTrace();
}

Marshal MATLAB Structures

If any MATLAB function in a deployable archive uses structures, you need to provide marshaling rules to the reflection-based proxy. To provide marshaling rules to the proxy:

  1. Implement a new set of marshaling rules by extending the MWDefaultMarshalingRules interface to use a list of the classes being marshaled.

  2. Create the proxy using the createComponentProxy(URL archiveURL, MWMarshalingRules marshalingRules) method.

The deployable archive studentChecker includes functions that use a MATLAB structure of the form

S = 
name: 'Ed Plum'
score: 83
grade: 'B+'

Java client code represents the MATLAB structure with a class named Student. To create a marshaling rule for dynamically invoking the functions in studentChecker, create a class named studentMarshaler.

class studentMarshaler extends MWDefaultMarshalingRules
{
  public List<Class> getStructTypes() {
    List structType = new ArrayList<Class>();
    structType.add(Student.class);
    return structType;
  }
}

Create the proxy for studentChecker by passing studentMarshaler to createComponentProxy().

URL archiveURL = new URL("http://localhost:9910/studentCheck");
myProxy =  myClient.createComponentProxy(archiveURL,
                                         new StudentMarshaler());

For more information about using MATLAB structures, see Marshal MATLAB Structures (Structs) in Java.