Monday, April 23, 2012

Matlab, PHP & Java


I am trying to create a web app which uses a Matlab function using a PHP/Java Bridge. Let me explain:



  1. I need to write the function in matlab

  2. convert the function into a jar file using the matlab ja builder

  3. Use a PHP/Java Bridge to call this function in php and display results.



So far I have done this. I created a very simple Matlab file named "makesqr.m" which is as below:




function y=makesqr(x)
y = magic(x);
end



I packaged this into a jar file named "themagic.jar" using Matlab builder JA. Installed Tomcat and PHP/Java Bridge and wrote a php function which calls the makesqr func like this:




<?php
require_once("http://localhost:8080/JavaBridgeTemplate621/java/Java.inc");
$myclass=new Java("themagic.mksqr");//mksqr is the class which has the method named makesqr
$input = new Java("java.lang.Double", 5);
$noofoutputs=new Java("java.lang.Integer",1);
$matinp=new Java("com.mathworks.toolbox.javabuilder.MWNumericArray",$input);
$myclass->makesqr($noofoutputs,$matinp);
?>



I just keep getting this error:




Uncaught [[o:Exception]:"java.lang.Exception: Invoke failed: [[o:mksqr]]->makesqr((o:int)[o:Integer], (o:Object;)[o:MWNumericArray]). Cause: java.lang.IllegalArgumentException: argument type mismatch VM: 1.6.0_25@http://java.sun.com/" at: #-9 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) #-8 sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) #-7 sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) #-6 java.lang.reflect.Method.invoke(Unknown Source) #-5 php.java.bridge.JavaBridge.Invoke(JavaBridge.java:1044) #-4 php.java.bridge.Request.handleRequest(Request.java:417) #-3 php.java.bridge.Request.handleRequests(Request.java:500) #-2 php.java.bridge.http.ContextRunner.run(ContextRunner.java:145) #-1 php.java.bridge.ThreadPool$Delegate.run(ThreadPool.java:60) #0 http://localhost:8080/JavaBridgeTemplate621/java/Java.inc(232 ): java_ThrowExceptionProxyFactory->getProxy(7, 'com.mathworks.t...', 'T', true) #1 http://localhost:8080/JavaBridgeTemplate621/java/Java.inc(360 ): java_Arg->get in http://localhost:8080/JavaBridgeTemplate621/java/Java.inc on line 195




I dont understand what is to be done here.



Edit:-@renick- Hi I used the caucho quercus and wrote the php file"testjava.php" as below:-




$myclass=new Java("themagic.theMagic");
$input = new Java("java.lang.Double", 5);
$output=new Java("java.lang.Integer",1);
$result=new Java("java.lang.Object");
$n=new Java("com.mathworks.toolbox.javabuilder.MWNumericArray",$input,MWClassID.DOUBLE);
$result=$myclass->makesqr($output,$n);



Now when I call this file as "localhost:8080/testjava.php". I get the below error:




HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

com.caucho.quercus.QuercusException: themagic.theMagic.makesqr: null
com.caucho.quercus.env.JavaMethod.invoke(JavaMethod.java:131)
com.caucho.quercus.env.JavaInvoker.callMethod(JavaInvoker.java:737)
com.caucho.quercus.env.JavaOverloadMethod.callMethod(JavaOverloadMethod.java:179)
com.caucho.quercus.program.JavaClassDef.callMethod(JavaClassDef.java:658)
com.caucho.quercus.env.JavaValue.callMethod(JavaValue.java:327)
com.caucho.quercus.expr.AbstractMethodExpr.eval(AbstractMethodExpr.java:97)
com.caucho.quercus.expr.ObjectMethodExpr.eval(ObjectMethodExpr.java:97)
com.caucho.quercus.expr.AbstractMethodExpr.evalCopy(AbstractMethodExpr.java:63)
com.caucho.quercus.expr.BinaryAssignExpr.eval(BinaryAssignExpr.java:88)
com.caucho.quercus.expr.Expr.evalTop(Expr.java:523)
com.caucho.quercus.statement.ExprStatement.execute(ExprStatement.java:67)
com.caucho.quercus.statement.BlockStatement.execute(BlockStatement.java:105)
com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:413)
com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:89)
com.caucho.quercus.env.Env.executePageTop(Env.java:3951)
com.caucho.quercus.env.Env.executeTop(Env.java:3892)
com.caucho.quercus.servlet.QuercusServletImpl.service(QuercusServletImpl.java:188)
com.caucho.quercus.servlet.QuercusServlet.service(QuercusServlet.java:594)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause

java.lang.NullPointerException
com.mathworks.toolbox.javabuilder.internal.MWMCR.invoke(MWMCR.java:492)
themagic.theMagic.makesqr(theMagic.java:158)
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.caucho.quercus.env.JavaMethod.invoke(JavaMethod.java:117)
com.caucho.quercus.env.JavaInvoker.callMethod(JavaInvoker.java:737)
com.caucho.quercus.env.JavaOverloadMethod.callMethod(JavaOverloadMethod.java:179)
com.caucho.quercus.program.JavaClassDef.callMethod(JavaClassDef.java:658)
com.caucho.quercus.env.JavaValue.callMethod(JavaValue.java:327)
com.caucho.quercus.expr.AbstractMethodExpr.eval(AbstractMethodExpr.java:97)
com.caucho.quercus.expr.ObjectMethodExpr.eval(ObjectMethodExpr.java:97)
com.caucho.quercus.expr.AbstractMethodExpr.evalCopy(AbstractMethodExpr.java:63)
com.caucho.quercus.expr.BinaryAssignExpr.eval(BinaryAssignExpr.java:88)
com.caucho.quercus.expr.Expr.evalTop(Expr.java:523)
com.caucho.quercus.statement.ExprStatement.execute(ExprStatement.java:67)
com.caucho.quercus.statement.BlockStatement.execute(BlockStatement.java:105)
com.caucho.quercus.program.QuercusProgram.execute(QuercusProgram.java:413)
com.caucho.quercus.page.InterpretedPage.execute(InterpretedPage.java:89)
com.caucho.quercus.env.Env.executePageTop(Env.java:3951)
com.caucho.quercus.env.Env.executeTop(Env.java:3892)
com.caucho.quercus.servlet.QuercusServletImpl.service(QuercusServletImpl.java:188)
com.caucho.quercus.servlet.QuercusServlet.service(QuercusServlet.java:594)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.32 logs.

Apache Tomcat/6.0.32



Would anyone have any idea as to what I am doing wrong?



Note: I dont know a word of Java but am stuck in a situation where I have to handle this


Source: Tips4all

7 comments:

  1. Since you already have a jar and tomcat installed. You can maybe just wrap it into a web-service. Write a small servlet mapped to this class and you can curl from php and get a json formatted output. (you can take the Matlab method's output in your wrapper code, convert to json and send the answer back).

    This will free you of all type conversions, both while sending and receiving data. Look into RestEasy for an even easier way of sending arguments. Although for simple applications, request.getparameter() with a cast to desired type works great.

    ReplyDelete
  2. I will suggest an alternative way to implement this.
    Since you already have a tomcat web container I would suggest that you may want to try Caucho Quercus which is a PHP implementation on the Java Virtual Machine.

    See especially this documentation example how easy it is to call into Java code.

    ReplyDelete
  3. Your Matlab function is expecting Integer instead of Double. You are providing input as Double. I hope this will solve ur problem. This is not java bridge problem with PHP.

    ReplyDelete
  4. why not just extend your java-code to output it to stdout or into a file, then use a system command to execute your java program and catch the output or read it from a file?

    ReplyDelete
  5. The problem is the type of arguments.

    int (primitive type) is required.
    Object is required.

    so :

    try to use primitive for the first argument not the "java.lang.Integer" -> "int"

    and / or

    change "com.mathworks.toolbox.javabuilder.MWNumericArray" for a type adapted for Double or Float (it seems to be used for Array)

    ReplyDelete
  6. You can also call a jar file using a easy way like that:

    <?php
    $output = shell_exec("java -jar themagic.jar $parameter");
    echo $output;
    ?>

    ReplyDelete
  7. Confirm that you have created your classes with public accessor.

    ReplyDelete