You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rpc-user@xml.apache.org by Sean Tuling <ST...@csir.co.za> on 2002/06/01 18:26:54 UTC

using persistent objects and jni

hi,
 
i am trying to use xml-rpc where a client starts up a persistent
service on the server and then utilises the service until it gets
shutdown.  in more detail, i am trying to use use matlab (mathematical
toolset) as a mathematical engine but via xml-rpc.  i am programming in
java.  for both server and client.  to pull in the matlab engine i have
needed to use JNI.  this is not a problem with a standalone program
which initialises the matlab engine (communication is achieved via
activex on windows and rsh/pipes on unix), can perform simple operations
and closes the engine (see listing 1).  when i try to use xml-rpc with
the apache implementation and the stand-alone webserver i can initialise
the matlab engine.  subsequently to this when i execute a method to do
some calculation the server seems to have lost the reference to the
matlab engine.  i have listed the server code in listing 2, and the
client code in listing 3.  being new to xml-rpc means i have not
understood the inner workings of calling methods etc, so i am probably
making a fundamental mistake in how the webserver operates with respect
to the service methods and have probably got by object muddled a bit.  

some info on the matlab methods:

openEngine to start the matlab instance, 
evalString to execute a command and 
closeEngine to shut the matlab instance down.

my understanding of the addHandler method of the object WebServer is
that it should create a new object instance of the server, which already
contains the matlab engine object - so why does it only communicate with
the engine in the initialiseEngine method and not any subsequent
methods?

my ultimate intention is to be able to start multiple matlab engines
that any one client can access over a period of time.

maybe i need to create a subclass of WebServer which contains the
matlab engine object?
 
any help would be greatly appreciated for an engineer (hacker in the
negative sense) rather than a programmer.
 
regards
sean
 
LISTING 1:
 
import java.io.*;
import java.util.*;
import matlabengine.*;
 
public class test {
 
  public static matengine eng;
 
  public static void main (String[] args) {
    int err;
    double[][] array = new double[300][5];
    double[][] retarr = new double[300][5];
 
    for (int i = 0;i<300;i++) {
      for (int j=0;j<5;j++) {
        array[i][j] = i*2+j;
      }
    }
 
    eng = new matengine();
    err = eng.openEngine(true);
    err = eng.test(1);
    err = eng.setOutputBuffer();
    err = eng.test(1);
    err = eng.evalString("a=1;");
    err = eng.evalString("b=a*5");
    err = eng.test(1);
    String output = eng.getOutputBuffer();
    System.out.println("Response = "+output);
    System.out.flush();
 //   Calendar calendar = new GregorianCalendar();
//    int before = calendar.get(Calendar.MILLISECOND);// +
calendar.get(Calendar.MILLISECOND)/1000.0;
    for (int i = 0;i<1000;i++) {
      err = eng.putArray("huh",array);
    }
    for (int i = 0;i<1000;i++) {
      retarr = eng.getArray("huh");
    }
//    int after = calendar.get(Calendar.MILLISECOND);// +
calendar.get(Calendar.MILLISECOND)/1000.0;
//    double diff = after - before;
//    System.out.println("Time elapsed =
"+calendar.get(Calendar.SECOND)+" "+before+" "+after);
/*    for (int i = 0;i<3;i++) {
      for (int j=0;j<5;j++) {
        System.out.println("Values for index "+i+" "+j+" =
"+retarr[i][j]);
      }
    }
*/
    err = eng.closeEngine();
  }
}
 
LISTING 2:
 
import java.io.*;
import java.util.*;
import org.apache.xmlrpc.*;
import matlabengine.*;
   
public class CalculationServer {
 
    private static WebServer server;
    private static int port;
 
    public static matengine engine;
    public static int engerror;
 
    public CalculationServer () {
//        engine = new matengine();
//        engerror = engine.openEngine(true);
//        if (engerror != 0) {
//          System.out.println("Problem starting Calculation
Server!");
//        } else {
//          engerror = engine.setOutputBuffer();
//        }
    }
 
    public Hashtable sumAndDifference (int x, int y) {
        Hashtable result = new Hashtable();
        result.put("sum", new Integer(x + y));
        result.put("difference", new Integer(x - y));
        return result;
    }
 
    public int newInstance(String name) {
        try {
            server.addHandler(name, new CalculationServer());
            System.out.println(" starting new handler: "+name);
            return(0);
        } catch (Exception exception) {
            System.err.println("MATLAB Calculation Server Error: Create
new instance:" + exception.toString());
            return(1);
        }    
    }
 
    public int initialiseEngine() {
        engine = new matengine();
        engerror = engine.openEngine(true);
        if (engerror != 0) {
          return(engerror);
        }
        engerror = engine.setOutputBuffer();
        engerror = engine.evalString("pwd");
        engerror = engine.evalString("a=1");
        System.out.println(getResponse());
        return(engerror);
    }
 
    public int executeCommand(String command) {
        int err;
        err = engine.evalString(command);
        return(err);
    }
 
    public String getResponse() {
        return(engine.getOutputBuffer());
    }
 
    public int closeEngine() {
        return(engine.closeEngine());
    }
 
    public static void main (String args[]) {
        try {
            if (args.length > 0) {
              port = Integer.valueOf(args[0]).intValue();
            }
            else {
              port = 8080;
            }
            server = new WebServer(port);
  server.addHandler("calc", new CalculationServer());
            System.out.println("MATLAB Calculation Server Startup");
            System.out.println(" on port "+port);
        } catch (Exception exception) {
            System.err.println("MATLAB Calculation Server Error: " +
exception.toString());
        }
    }
}
 
LISTING 3:
 
    import java.util.*;
    import org.apache.xmlrpc.*;
   
    public class CalculationClient {
   
        // The location of our server.
        private final static String server_url =
            "http://localhost:8080/RPC2";
   
        public static void main (String [] args) {
            Integer res;
            int err;
            String sres;
            try {
   
                // Create an object to represent our server.
//      for (int i=0;i<100;i++) {
                XmlRpcClient server = new XmlRpcClient(server_url);
   
                // Build our parameter list.
                Vector params = new Vector();
 
                params.addElement(new Integer(5));
                params.addElement(new Integer(3));
   
                // Call the server, and get our result.
                Hashtable result =
                    (Hashtable) server.execute("calc.sumAndDifference",
params);
                int sum = ((Integer) result.get("sum")).intValue();
                int difference = ((Integer)
result.get("difference")).intValue();
   
                // Print out our result.
                System.out.println("Sum: " + Integer.toString(sum) +
                                   ", Difference: " +
                                   Integer.toString(difference));
 
                params = new Vector();
                res = (Integer)
server.execute("calc.initialiseEngine",params);
                err = res.intValue();
                System.out.println("Return value = "+err);
 
                params = new Vector();
                params.addElement(new String("a=5;"));
                res = (Integer)
server.execute("calc.executeCommand",params);
                err = res.intValue();
                System.out.println("Return value = "+err);
 
                params = new Vector();
                sres = (String)
server.execute("calc.getResponse",params);
                System.out.println("Return = "+sres);
 
                params = new Vector();
                res = (Integer)
server.execute("calc.closeEngine",params);
                err = res.intValue();
                System.out.println("Return value = "+err);
 
//                }   
            } catch (XmlRpcException exception) {
                System.err.println("JavaClient: XML-RPC Fault #" +
                                   Integer.toString(exception.code) +
": " +
                                   exception.toString());
            } catch (Exception exception) {
                System.err.println("JavaClient: " +
exception.toString());
            }
        }
    }