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:
Instantiate an instance of the MWHttpClient
class.
Create a reflection-based proxy object using one of the createComponentProxy()
methods
of the client connection.
Invoke the function using one of the invoke()
methods
of the reflection-based proxy.
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);
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
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.
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(); }
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(); }
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:
Implement a new set of marshaling rules by extending the MWDefaultMarshalingRules
interface
to use a list of the classes being marshalled.
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 marshalling
rule for dynamically invoking the functions in studentChecker
,
create a class named studentMarshaller
.
class studentMarshaller extends MWDefaultMarshalingRules { public List<Class> getStructTypes() { List structType = new ArrayList<Class>(); structType.add(Student.class); return structType; } }
Create the proxy for studentChecker
by passing studentMarshaller
to createComponentProxy()
.
URL archiveURL = new URL("http://localhost:9910/studentCheck"); myProxy = myClient.createComponentProxy(archiveURL, new StudentMarshaller());
For more information about using MATLAB structures, see Marshal MATLAB Structures (Structs) in Java.