On the client side, you set parameters to be sent to the server using the JWaveExecute.
setParam method. These parameters are not actually sent to the server until the execute
method is called. After an execute
, the client may retrieve parameters returned by the wrapper function using JWaveExecute.getReturnData
(to get one parameter at a time) or getReturnParams
(to get all the parameters at once).
On the server side, parameters passed from the client can be retrieved in a JWAVE wrapper with the GETPARAM function (a JWAVE-specific PV-WAVE function). When a wrapper function returns, its return values are automatically sent to the client.
Figure 3-1 Parameters and data are passed between the Java client and the JWAVE wrapper. Java methods and special PV-WAVE functions are used to package and extract the data and parameters.
NOTE: This chapter does not cover the topic of data proxies, which allow data stored on the server to be referenced by the client. Proxies permit the efficient management of data and of client resources. For detailed information on proxies, see Chapter 6, Managing Data.
execute
method sends the parameters that were set (with setParam
methods) to the wrapper, causes the wrapper to execute, and retrieves any returned data. You can construct a
JWaveExecute
object simply by giving the JWAVE wrapper name:
JWaveExecute(String wrappername)
JWaveExecute
object to a new PV-WAVE session. That is, a new JWaveConnection
object is created automatically.
TIP: After construction, you can call a different JWAVE wrapper function, if desired, using the methodsetFunction
.
JWaveConnection
object that refers to an existing PV-WAVE session, then you can construct a JWaveExecute
object to use that same connection. For example:
JWaveExecute(JWaveConnection connection, String name)
JWaveExecute
objects that need to use the same PV-WAVE session (in other words, they need to share data), or if you want to set particular attributes of the connection (such as data compression or a session pinger). The following method creates a
JWaveConnection
object:
static JWaveConnection.getConnection()
JWaveExecute.getConnection()
JWaveExecute.setParam
method is used to pack parameters and data on the client to be sent to the server. The basic information that is packed by setParam
includes a parameter name and some kind of reference to data.
Overloaded versions of
setParam
are provided for your convenience in specifying this parameter information. setParam
configurations are: setParam(String name, double value)
NOTE: Parameter names are not case sensitive; they must begin with a letter, and can contain only letters, digits, and underscores.
setParam(String name, Object value)
setParam
method include:Scalar Values:
Integer
), except Long
· String
Integer
)
· numeric primitives (such as int
), except long
· String
setParam(Parameter param)
Parameter
object (which encapsulates the parameter name and associated data).
setParam
. Some of these are discussed in Chapter 6, Managing Data. Others are not commonly used, and are not discussed in this manual. Refer to the Javadoc reference on the JWaveExecute class for detailed information on all of the setParam
methods. For information on Javadoc, see Using the JWAVE Javadoc Reference.
As you can see, the different permutations of
setParam
allow you to specify precisely how you want parameters to be sent to the client. No matter how this parameter information is specified, setParam
"packs" the parameter information in a uniform manner so that the server can retrieve and unpack the parameters.
JWaveExecute.getReturnData
method. This method accepts one parameter: the name of the returned data. This data name is specified by the JWAVE wrapper, but if a name is not explicitly specified, the default name DATA
is used. Of course, a JWAVE wrapper can return many data objects at once. You have to know the names of those objects (given in the JWAVE wrapper) to unpack them. The method
getReturnProxy
is similar to getReturnData
, except that it returns a Proxy
object that refers to the data. This is useful when the data is stored on the server. For more information on using proxies, see Chapter 6, Managing Data.
TIP: For debugging purposes, the following command can be useful:
Parameter.printInfo( myJWaveExecute.getReturnParams() );
System.out
) the names and data types of all parameters returned by the JWAVE wrapper.
getReturnData
is of type Object. This object may be a scalar or a multi-dimensional array, depending on what was returned by the JWAVE wrapper. Numerical scalars are returned as one of the
java.lang.Number
subclasses (java.lang.Integer
, java.lang.Float
, and so on.). Numerical arrays are returned as an array of one of the primitive numeric types (such as int[]
or float[][]
). Strings are returned as java.lang.String
, java.lang.String[]
, and so on.In order to make the data returned by
getReturnData
useful, you need to cast it to something. For example, if you are sure of the data type and array dimensions returned by the wrapper, you can write a statement such as:
int[][] result = (int[][]) myJWaveExecute.getReturnData("DATA_NAME");
If you are unsure of the data type (PV-WAVE is a loosely-typed language), then you must test the returned Object for its type. Usually, you will know something about the data, such as its number of array dimensions, whether it is a string or a number, and so on. So usually you will only need to test for (or assume) things like array size and then just cast or assign the result to whatever variable you will use in the Java program.
Of course, you can use the
instanceof
operator to test for particular types. The classes
java.lang.Class
, java.lang.reflect.Array
, and
com.visualnumerics.util.ArrayUtils are other useful tools for dealing with the object returned by getReturnData
. Some examples of using these classes are shown in the following example:
Example 3-1 Array handling
Object result = myJWaveExecute.getReturnData("DATA_NAME"); // Test if the returned object is an array if ( result.getClass().isArray() ) { System.out.println("Is Array"); // Get the size of the array (i.e. [3][4][5]) int[] dims = ArrayUtils.getArrayDimensions(result); System.out.println("Num Dims = "+ dims.length); System.out.print("Dims = "); for (int i=0; idims.length; ++i) System.out.println("[" + dims[i] + "]"); System.out.println(); // Get data type of array's contents // Note that result.getClass() just tells you that it is an array // And Class.getComponentType() is only useful for 1D arrays // This gives you the Class of the contents of the array, // no matter the dimensional size of the array Class c = ArrayUtils.getBaseComponentType(result); System.out.println("Type = " + c.getName()); // store into double[] // Ensure 1D numeric array if (dims.length == 1 && !String.class.isAssignableFrom(c)) { double[] dblResult = new double[dims[0]]; // Store into double array for (int i=0; i
dblResult.length; ++i) dblResult[i] = Array.getDouble(result, i); System.out.println("Stored into double[]."); } else { // Do different things for multi-dim arrays, strings... // See ArrayUtils.getAsOneDimArray(), for example } } else { // not array System.out.println("Is Scalar"); System.out.println("Type = " + result.getClass().getName()); // Store into int scalar if (result instanceof Number) { double dblResult = ((Number)result).doubleValue(); System.out.println("Stored into double = "+ dblResult); } else { // Do different things for strings... } }
JWaveConnectionException JWaveConnectInfo.jar
file).
JWaveServerException
Indicates a problem with the JWAVE server. You were able to connect to the server, but it produced an error. It may not have been able to start PV-WAVE. You may have run out of JWAVE licences. The server may not have been able to find or run your intended wrapper function.
JWaveWrapperException
The JWAVE wrapper function was executed, but exited with an error. The exception text comes from the PV-WAVE MESSAGE procedure (or !Err_String system variable).
JWaveConnection.getConnection
method, or implicitly by constructing a JWaveExecute object (without using a JWaveConnection
object in the constructor), and using that JWaveExecute.getConnecton
method.
setCompression
method. Compression can be turned on and off, allowing you to make some execute
calls on a compressed connection and others without compression. Generally, compression is beneficial for transferring large data sets (especially graphics, which are usually very compressible) over relatively slow networks. If you have a fast network connection to the server, you may not want to use compression
shutdown method of JWaveConnection. This closes the PV-WAVE session, releasing any resources (memory, JWAVE licenses, and so on) that it was using on the server. myJWaveExecute.getConnection().shutdown();
setSessionID
before you contact the server (using methods such as pingSession
and execute
). If that PV-WAVE session is running, then you will be connected with it. If it is not running, then it will be started.
pingManager
andpingSession
. The pingManager
method allows you to make sure that the JWAVE Manager is alive, and pingSession
ensures that your PV-WAVE session has not timed out. The
pingSession
method can also be used to start a PV-WAVE session. This can help performance; for example, you may call pingSession
at the beginning of your application so that the PV-WAVE session will be activated by the time the user presses the Plot
button of your GUI.In order to keep the PV-WAVE session alive (prevent the JWAVE Manager from killing the session if it is idle too long), use the
startSessionPinger
method. This method starts a thread that will call pingSession
every minute (by default) until you call stopSessionPinger
or shutdown
. This keeps your PV-WAVE session from becoming idle.
TIP: If you usestartSessionPinger
in all of your JWAVE applications, then your JWAVE Server administrator can reduce theSESSION_IDLE_TIMEOUT
setting, so that idle processes can be cleaned up more often.
Figure 3-2 Data is passed from client to server, and the server returns a data object, which is then printed by the client.
Example 3-2 Client application passes an array to the server, retrieves a result, and prints it
import com.visualnumerics.jwave.JWaveExecute; import com.visualnumerics.jwave.JWaveConnection; public class PassArray { public static void main(String[] args) { JWaveExecute command = null; // Create a simple array of data values. float arr[] = new float[10]; for (int k=0; karr.length; k++) { arr[k]=k; } try { // Pass the array parameter to the server to use with // the PASSARR JWAVE wrapper function. command = new JWaveExecute(
"
PASSARR"); command.setParam("
ARRAY", arr); command.execute(); // Get the data Object returned from the server and cast // to float array. float d[]= (float[]) command.getReturnData("
DATA"); //Print the returned array. for (int j=0; jd.length; j++) { System.out.println(d[j]); } } catch (Exception e) { System.out.println(e.toString()); } finally { if (command != null) { JWaveConnection c = command.getConnection(); if (c != null) c.shutdown(); } } }
Example 3-3 JWAVE wrapper function receives the array, changes it, and returns it to the client
FUNCTION PASSARR, client_data ; Unpack parameters and data arr = GETPARAM(client_data, 'ARRAY', /Value, Default=[1.,2.,3.]) ; change the array mydata = arr * 1.5 ; return the changed array and ensure FLOAT data type RETURN, FLOAT(mydata) END
% java PassArray 0.0 1.5 3.0 4.5 6.0 7.5 9.0 10.5 12.0 13.5 %
VNI_DIR/classes/docs/api/packages.html
VNI_DIR\classes\docs\api\packages.html
VNI_DIR
is the main Visual Numerics installation directory.
execute
method is called. The methods getReturnedData
, getReturnParams
, and getReturnProxy
are all used to retrieve data returned from the server. Sometimes it is necessary to cast the returned data to the desired data type. The JWaveConnection class allows you to create and manipulate the JWAVE client-server connection. Client-server connection and JWAVE wrapper errors are handled by a set of JWaveException subclasses.