Search code examples
javajspmatlab-deployment

Problems integrating Matlab with Java for deployment in web


I am seriously new to Matlab and Matlab Builder JA. I am trying to make a simple Java web by calling a Matlab functions. So, I have model.m file. I have put in the functions to be used as a library to run in a server and have some variables to be input by users, which are 'Time' (eg. 20) and 'Dose' (eg. 1 2 0 0). I have tried to integrate all the codes and include the Matlab library. But unfortunately, only the .html file can be run. Below are my codes and error that I get. Hope someone could help me to check whether I am compiling the model.m file correctly and the Java file is coded also correct. For your information, I am using Eclipse Kepler and Tomcat 7.0.54. Thanks in advance!

First of all, this is the error that I got when I run the application.

EDITED HTTP Status 500-

java.lang.NullPointerException
com.mathworks.toolbox.javabuilder.internal.MWMCR.mclFeval(Native Method)
com.mathworks.toolbox.javabuilder.internal.MWMCR.access$600(MWMCR.java:23)
com.mathworks.toolbox.javabuilder.internal.MWMCR$6.mclFeval(MWMCR.java:833)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
com.mathworks.toolbox.javabuilder.internal.MWMCR$5.invoke(MWMCR.java:731)
com.sun.proxy.$Proxy11.mclFeval(Unknown Source)
com.mathworks.toolbox.javabuilder.internal.MWMCR.invoke(MWMCR.java:406)
runPKmodelV1.Function.runPKmodelV1(Function.java:217)
SecondServlet.doGet(SecondServlet.java:78)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

This is the model.m file that have all the functions needed, with an output figure.

MATLAB model.m

function w = model(tf_sim,y0)
%%--------------------------------------------------------------------
% Running ODE model - Initial Conditions and setting up ode solver
%---------------------------------------------------------------------

%Initial Conditions:

%Initial Conditions:
% Dose_Central = 1;
% Drug_Central = 0;
% Dose_Peripheral = 0;
% Drug_Peripheral = 0;

%tf_sim=10;   %Simulation time
% y0(1) = 1;  % Dose in Central Compartment
% y0(2) = 0;  % Drug in Central Compartment
% y0(3) = 0;  % Dose in Peripheral Compartment
% y0(4) = 0;  % Drug in Peripheral Compartment

options = odeset('RelTol',1e-4,'AbsTol',1e-5);

%%% Solving ODEs, final time = 2e+9 sec (aprox. 63 years) %%%
[t,y]=ode15s(@PK_Model_v1,[0 tf_sim],y0,options);

%%% Plotting state variables %%%
f = figure;

subplot(2,2,1);
plot(t,y(:,1),'r-');
subplot(2,2,2);
plot(t,y(:,2),'b-');
subplot(2,2,3);
plot(t,y(:,3),'m-');
subplot(2,2,4);
plot(t,y(:,4),'k-');

w = webfigure(f);
close(f);

end


function dy = PK_Model_v1(time,y)

%Parameter Values:

Tk0_Central = 1;
TLag_Central = 1;
Km_Central = 1;
Vm_Central = 30;
Tk0_Peripheral = 1;
TLag_Peripheral = 1;
Q12 = 1;
k12 = 1;
k21 = 1;
Central = 1;
Peripheral = 1;
ka_Central = 0.5;
ka_Peripheral = 0.1;

%Fluxes:
ReactionFlux1 = ka_Central*y(1);
ReactionFlux2 = Vm_Central*y(2)/(Km_Central+y(2));
ReactionFlux3 = ka_Peripheral*y(3);
ReactionFlux4 = (k12*y(2))*Central-(k21*y(4))*Peripheral;

dy(1,1) = -ReactionFlux1;
dy(2,1) = 1/Central*(ReactionFlux1 - ReactionFlux2 - ReactionFlux4);
dy(3,1) = -ReactionFlux3;
dy(4,1) = 1/Peripheral*(ReactionFlux3 + ReactionFlux4);


end

This is the welcome page, with all the variables to be input by users.

Eclipse page.html

<form action="SecondServlet">
    <p>&nbsp;</p>

    <p>PK Model Example</p>
    <p>&nbsp;</p>

    <p>Time</p>
    <input type="text" name="tf_sim" value="" />

    <p>Dosage</p>
    <input type="text" name="y0" value="" />

    <!-- Submit -->
    <input type="submit" value="Display" name="DoPLot" />
    <p>&nbsp;</p>
</form>

There is nothing in the index.jsp page. Only the webfigure after the submit button from page.html is clicked.

Eclipse index.jsp

<div ALIGN="CENTER">
    <wf:web-figure root="WebFigures" name="Project_Figure" scope="session" />
</div>

This consists of codes used to get the data keyed in by the users and finally calculate the result with the use of Matlab library and dispatch the result into the index.jsp.

EDITED Eclipse SecondServlet.java

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    Object[] param = new MWArray[2];
    Object[] result = null;

    param[0] = new MWNumericArray(Integer.parseInt(request
            .getParameter("tf_sim")), MWClassID.DOUBLE);

            String[] str_elems = request.getParameter("y0").split("\\s+");
    int[] numbers = new int[str_elems.length];
    for (int i = 0; i < str_elems.length; i++) {
        numbers[i] = Integer.parseInt(str_elems[i]);
    }

    try {

        result = pkModel.model(1, param);
        WebFigure webFig = (WebFigure) ((MWJavaObjectRef) result[0]).get();

        // Set the figure scope to session
        request.getSession().setAttribute("Project_Figure", webFig);
        // Bind the figure's lifetime to session
        request.getSession().setAttribute("Project_Figure_Binder",
                new MWHttpSessionBinder(webFig));

        updateSession(request.getSession(), result);
        RequestDispatcher dispatcher = request
                .getRequestDispatcher("/index.jsp");
        dispatcher.forward(request, response);

    } catch (MWException e) {
        e.printStackTrace();
    } finally {
        MWArray.disposeArray(result);
    }
}

public void updateSession(HttpSession session, Object[] param) {
    int outputCount = param.length - 1;
    session.setAttribute("numOutputs", outputCount);

}

Really hope someone could help. Thanks!


Solution

  • Take a look at the error message:

    java.lang.NumberFormatException: For input string: "1 2 0 0"
    java.lang.NumberFormatException.forInputString(Unknown Source)
    java.lang.Integer.parseInt(Unknown Source)
    java.lang.Integer.parseInt(Unknown Source)
    SecondServlet.doGet(SecondServlet.java:70)
    

    The first line states that the problem is the number format, the third tells us that it encounter the problem when using the parseInt method, and the last line tells us it's in the doGet method.

    Taking a quick look at the doGet method, we see:

    param[1] = new MWNumericArray(Integer.parseInt(request
            .getParameter("y0")), MWClassID.DOUBLE);
    

    Now, judging by your comments on the data format earlier y0 is meant to be an array of four numbers. The problem then is that Interger.parseInt is meant for parsing single numbers, not arrays of them.

    To solve this you would need to add a separate step to split your input into individual numbers and parse them one at a time. Something like this:

    String[] str_elems = request.getParameter("y0").split(" ");
    List<Integer> int_elems = new LinkedList<Integer>();
    for (int i = 0; i < str_elems.length; i++) 
      int_elems.add(Integer.parseInt(str_elems[i]));
    

    Or something similar, modified to account for the input preferences of MWNumericArray, documentation for which I couldn't find.