BEA Logo BEA Tuxedo Release 7.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   Tuxedo Doc Home   |   Jolt   |   Topic List   |   Previous   |   Next   |   Contents   |   Index

   Using BEA Jolt

Using BEA Tuxedo Buffer Types with Jolt

Jolt supports the following built-in BEA Tuxedo buffer types:

For information about all the BEA Tuxedo typed buffers, data types, and buffer types, refer to the following documents:

Of the BEA Tuxedo built-in buffer types, the Jolt application programmer should be particularly aware of how Jolt handles the CARRAY (character array) and STRING built-in buffer types. The CARRAY type is used to handle data opaquely (for example, the characters of a CARRAY data type are not interpreted in any way). No data conversion is performed between a Jolt client and BEA Tuxedo service.

For example, if a BEA Tuxedo service uses a CARRAY buffer type and the user sets a 32-bit integer (in Java the integer is in big-endian byte order), then the data is sent unmodified to the BEA Tuxedo service. If the BEA Tuxedo service is run on a machine whose processor uses little-endian byte-ordering (for example, Intel processors), the BEA Tuxedo service must convert the data properly before the data can be used.

Using the STRING Buffer Type

The STRING buffer type is a collection of characters. STRING consists of non-null characters and is terminated by a null character. The STRING data type is character and, unlike CARRAY, you can determine its transmission length by counting the number of characters in the buffer until reaching the null character.

Note: During the data conversion from Jolt to STRING, the null terminator is automatically appended to the end of the STRING buffers because a Java string is not null-terminated.

Using the STRING buffer type requires two main steps:

  1. Define the Tuxedo service that you will be using with the buffer type.

  2. Write the code that uses the STRING buffer type.

The next two sections provide examples that demonstrate these steps.

The ToUpper code fragment shown in the listing Use of the STRING buffer type (ToUpper.java) illustrates how Jolt works with a service whose buffer type is STRING. The TOUPPER BEA Tuxedo Service is available in the BEA Tuxedo simpapp example.

Define TOUPPER in the Repository Editor

Before running the ToUpper.java example, you need to define the TOUPPER service through the Jolt Repository Editor.

Note: Refer to Using the Jolt Repository Editor for more information about defining your services and adding new parameters.

  1. In the Jolt Repository Editor Logon window, click Services.

  2. In the Services window, locate the TOUPPER service in the SIMPSERV package.

  3. Click Edit.

    Add a TOUPPER Service

  4. In the Edit Services window, define an input buffer type of STRING and an output buffer type of STRING. Refer to the figure Set Input and Output Buffer Types to STRING.)

  5. For the TOUPPER service, define only one parameter for the TOUPPER service named STRING that is both an input and an output parameter.

    Set Input and Output Buffer Types to STRING

ToUpper.java Client Code

The ToUpper.java Java code fragment in the following listing illustrates how Jolt works with a service with a buffer type of STRING. The example shows a Jolt client using a STRING buffer to pass data to a server. The BEA Tuxedo server would take the buffer, convert the string to all uppercase letters, and pass the string back to the client. The following example assumes that a session object was already instantiated.

Use of the STRING buffer type (ToUpper.java)


/* Copyright 1996 BEA Systems, Inc.  All Rights Reserved */
import bea.jolt.*;
public class ToUpper
{
public static void main (String[] args)
{
JoltSession session;
JoltSessionAttributes sattr;
JoltRemoteService toupper;
JoltTransaction trans;
String userName=null;
String userPassword=null;
String appPassword=null;
String userRole="myapp";
String outstr;

        sattr = new JoltSessionAttributes();
sattr.setString(sattr.APPADDRESS, "//myhost:8501");

        switch (sattr.checkAuthenticationLevel())
{
case JoltSessionAttributes.NOAUTH:
break;
case JoltSessionAttributes.APPASSWORD:
appPassword = "appPassword";
break;
case JoltSessionAttributes.USRPASSWORD:
userName = "myname";
userPassword = "mysecret";
appPassword = "appPassword";
break;
}
sattr.setInt(sattr.IDLETIMEOUT, 300);
session = new JoltSession(sattr, userName, userRole,
userPassword, appPassword);
toupper = new JoltRemoteService ("TOUPPER", session);
toupper.setString("STRING", "hello world");
toupper.call(null);
outstr = toupper.getStringDef("STRING", null);
if (outstr != null)
System.out.println(outstr);

        session.endSession();
System.exit(0);
} // end main
} // end ToUpper


Using the CARRAY Buffer Type

The CARRAY buffer type is a simple character array buffer type that is built into the BEA Tuxedo system. Because the system does not interpret the data (although the data type is known) when you use the CARRAY buffer type, you must specify a data length in the Jolt client application. The Jolt client must specify a datalength when passing this buffer type.

To use the CARRAY buffer type, you first define the Tuxedo service that you will be using with the buffer type. Then, write the code that uses the buffer type. The next two sections demonstrate these steps.

Note: X_OCTET is used identically to CARRAY.

Define the Tuxedo Service in the Repository Editor

Before running the example shown in the figure Add a TOUPPER Service, you must write and boot an ECHO BEA Tuxedo service. The ECHO service takes a buffer and passes it back to the Jolt client. You define the ECHO service in the Jolt Repository Editor.

Repository Editor: Add the ECHO Service

Use the Repository Editor to add the ECHO service as follows:

  1. In the Repository Editor, add a service called ECHO. Refer to Instructions for Adding a Service and Instructions for Adding a Parameter.

  2. Define the input buffer type and output buffer type as CARRAY for the ECHO service.

  3. Define the ECHO service with only one parameter named CARRAY that is both an input and output parameter.

    Note: If using the X_OCTET buffer type, you must change the Input Buffer Type and Output Buffer Type fields to X_OCTET.

    Repository Editor: Edit ECHO Service

tryOnCARRAY.java Client Code

The code in the following listing illustrates how Jolt works with a service with a buffer type of CARRAY. Because Jolt does not look into the CARRAY data stream, it is the programmer's responsibility to ensure that the data formats between the Jolt client and the CARRAY service match. The example in the following listing assumes that a session object was already instantiated.

CARRAY Buffer Type Example


/* Copyright 1996 BEA Systems, Inc. All Rights Reserved */

  /* This code fragment illustrates how Jolt works with a service  
* whose buffer type is CARRAY.
*/

import java.io.*;
import bea.jolt.*;
class ...
{
...
public void tryOnCARRAY()
{
byte data[];
JoltRemoteService csvc;
DataInputStream din;
DataOutputStream dout;
ByteArrayInputStream bin;
ByteArrayOutputStream bout;
/*
* Use java.io.DataOutputStream to put data into a byte array
*/
bout = new ByteArrayOutputStream(512);
dout = new DataOutputStream(bout);
dout.writeInt(100);
dout.writeFloat((float) 300.00);
dout.writeUTF("Hello World");
dout.writeShort((short) 88);
/*
* Copy the byte array into a new byte array "data". Then
* issue the Jolt remote service call.
*/
data = bout.toByteArray();
csvc = new JoltRemoteService("ECHO", session);
csvc.setBytes("CARRAY", data, data.length);
csvc.call(null);
/*
* Get the result from JoltRemoteService object and use
* java.io.DataInputStream to extract each individual value
* from the byte array.
*/
data = csvc.getBytesDef("CARRAY", null);
if (data != null)
{
bin = new ByteArrayInputStream(data);
din = new DataInputStream(bin);
System.out.println(din.readInt());
System.out.println(din.readFloat());
System.out.println(din.readUTF());
System.out.println(din.readShort());
}
}
}


Using the FML Buffer Type

FML (Field Manipulation Language) is a flexible data structure that can be used as a typed buffer. The FML data structure stores tagged values that are typed, variable in length, and may have multiple occurrences. The typed buffer is treated as an abstract data type in FML.

FML gives you the ability to access and update data values without having to know how the data is structured and stored. In your application program, you simply access or update a field in the fielded buffer by referencing its identifier. To perform the operation, the FML run time determines the field location and data type.

FML is especially suited for use with Jolt clients because the client and server code can be in two languages (for example, Java and C); the client/server platforms can have different data type specifications; or the interface between the client and the server can change frequently.

The following tryOnFml examples illustrate the use of the FML buffer type. The examples show a Jolt client using FML buffers to pass data to a server. The server takes the buffer, creates a new FML buffer to store the data, and passes that buffer back to the Jolt client. The examples consist of the following components.

tryOnFml.java Client Code

The tryOnFml.java Java code fragment in the following listing illustrates how Jolt works with a service whose buffer type is FML. In this exampl, it is assumed that a session object was already instantiated.

tryOnFml.java Code Example


/* Copyright 1997 BEA Systems, Inc. All Rights Reserved */

import bea.jolt.*;
class ...
{
...
public void tryOnFml ()
{
JoltRemoteService passFml;
String outputString;
int outputInt;
float outputFloat;
...
passFml = new JoltRemoteService("PASSFML",session);
passFml.setString("INPUTSTRING", "John");
passFml.setInt("INPUTINT", 67);
passFml.setFloat("INPUTFLOAT", (float)12.0);
passFml.call(null);
outputString = passFml.getStringDef("OUTPUTSTRING", null);
outputInt = passFml.getIntDef("OUTPUTINT", -1);
outputFloat = passFml.getFloatDef("OUTPUTFLOAT", (float)-1.0);
System.out.print("String =" + outputString);
System.out.print(" Int =" + outputInt);
System.out.println(" Float =" + outputFloat);
}
}


FML Field Definitions

The entries in the following listing,tryOnFml.f16 Field Definitions, show the FML field definitions for the previous listing, tryOnFml.java Code Example.

tryOnFml.f16 Field Definitions


#
# FML field definition table
#
*base 4100
INPUTSTRING 1 string
INPUTINT 2 long
INPUTFLOAT 3 float
OUTPUTSTRING 4 string
OUTPUTINT 5 long
OUTPUTFLOAT 6 float


Define PASSFML in the Repository Editor

The BULKPKG package contains the PASSFML service, which is used with the tryOnFml.java and tryOnFml.c code. Before running the tryOnFml.java example, you need to modify the PASSFML service through the Jolt Repository Editor.

Note: Refer to Using the Jolt Repository Editor for more information about defining a service.

  1. In the Edit Services window of the Jolt Repository Editor, define the PASSFML service with an input buffer type of FML and an output buffer type of FML.

    The figure Repository Editor Window: Edit Services (PASSFML) illustrates the PASSFML service, and Input Buffer and Output Buffer of FML.

    Repository Editor Window: Edit Services (PASSFML)

  2. Select the input buffer type and output buffer type as FML for the PASSFML service.

  3. Click Edit to display the Edit Parameters window as shown in the following figure.

    Edit the PASSFML Parameters

  4. Define the parameter for the PASSFML service.

  5. Repeat steps 2 - 4 for each parameter in the PASSFML service.

tryOnFml.c Server Code

The following listing illustrates the server side code for using the FML buffer type. The PASSFML service reads in an input FML buffer and outputs a FML buffer.

tryOnFml.c Code Example


/*

 * tryOnFml.c 
*
* Copyright (c) 1997 BEA Systems, Inc. All rights reserved
*
* Contains the PASSFML BEA Tuxedo server.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <fml.h>
#include <fml32.h>
#include <Usysflds.h>
#include <atmi.h>
#include <userlog.h>
#include "tryOnFml.f16.h"
/*
* PASSFML service reads in a input fml buffer and outputs a fml buffer.
*/
void
PASSFML( TPSVCINFO *rqst )
{
FLDLEN len;
FBFR *svcinfo = (FBFR *) rqst->data;
char inputString[256];
long inputInt;
float inputFloat;
FBFR *fml_ptr;
int rt;
if (Fget(svcinfo, INPUTSTRING, 0, inputString, &len) < 0) {
(void)userlog("Fget of INPUTSTRING failed %s",
Fstrerror(Ferror));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
if (Fget(svcinfo, INPUTINT, 0, (char *) &inputInt, &len) < 0) {
(void)userlog("Fget of INPUTINT failed %s",Fstrerror(Ferror));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
if (Fget(svcinfo, INPUTFLOAT, 0, (char *) &inputFloat, &len) < 0) {
(void)userlog("Fget of INPUTFLOAT failed %s",
Fstrerror(Ferror));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
/* We could just pass the FML buffer back as is, put lets */
/* store it into another FML buffer and pass it back. */
if ((fml_ptr = (FBFR *)tpalloc("FML",NULL,rqst->len))==(FBFR *)NULL) {
(void)userlog("tpalloc failed in PASSFML %s",
tpstrerror(tperrno));
tpreturn(TPFAIL, 0, rqst->data, 0L, 0);
}
if(Fadd(fml_ptr, OUTPUTSTRING, inputString, (FLDLEN)0) == -1) {
userlog("Fadd failed with error: %s", Fstrerror(Ferror));
tpfree((char *)fml_ptr);
tpreturn(TPFAIL, 0, NULL, 0L, 0);
}
if(Fadd(fml_ptr, OUTPUTINT, (char *)&inputInt, (FLDLEN)0) == -1) {
userlog("Fadd failed with error: %s", Fstrerror(Ferror));
tpfree((char *)fml_ptr);
tpreturn(TPFAIL, 0, NULL, 0L, 0);
}
if(Fadd(fml_ptr, OUTPUTFLOAT, (char *)&inputFloat, (FLDLEN)0) == -1) {
userlog("Fadd failed with error: %d\n", Fstrerror(Ferror));
tpfree((char *)fml_ptr);
tpreturn(TPFAIL, 0, NULL, 0L, 0);
}
tpreturn(TPSUCCESS, 0, (char *)fml_ptr, 0L, 0);
}


Using the VIEW Buffer Type

VIEW is a built-in BEA Tuxedo typed buffer. The VIEW buffer provides a way to use C structures and COBOL records with the BEA Tuxedo system. The VIEW typed buffer enables the BEA Tuxedo run-time system to understand the format of C structures and COBOL records based on the view description that is read at run time.

When allocating a VIEW, your application specifies a VIEW buffer type and a subtype that matches the name of the view (the name that appears in the view description file). The parameter name must match the field name in that view. Because the BEA Tuxedo run-time system can determine the space needed based on the structure size, your application need not provide a buffer length. The run-time system can also automatically handle such things as computing how much data to send in a request or response, and handle encoding and decoding when the message transfers between different machine types.

The following examples show the use of the VIEW buffer type with a Jolt client and its server-side application.

The Jolt client treats a null character in a VIEW buffer string format as an end-of-line character and truncates any part of the string that follows the null.

Define VIEW in the Repository Editor

Before running the simpview.java and simpview.c examples, you need to define the VIEW service through the Jolt Repository Editor.

Note: Refer to Using the Jolt Repository Editor for more information about defining a service.

Repository Editor: Add SIMPVIEW Service

In the Repository Editor add the VIEW service as follows:

  1. Add a SIMPVIEW service for the SIMPSERV package.

  2. Define the SIMPVIEW service with an input buffer type of VIEW and an output buffer type of VIEW.

    Repository Editor: Edit SIMPVIEW Service

  3. Define the parameters for the VIEW service.

    In this example the parameters are: inInt, inString, outFloat, outInt, outString.

    Note: If using the X_COMMON or X_C_TYPE buffer types, you must put the correct buffer type in the Input Buffer Type and Output Buffer Type fields. Additionally, you must choose the corresponding Input View Name and Output View Name fields.

simpview.java Client Code

The listing simpview.java Code Example illustrates how Jolt works with a service whose buffer type is VIEW. The client code is identical to the code used for accessing an FML service.

Note: The code in the following listing does not catch any exceptions. Because all Jolt exceptions are derived from java.lang.RunTimeException, the Java Virtual Machine (JVM) catches these exceptions if the application does not. (A well-written application would catch these exceptions, and take appropriate actions.)

Before running the example in the following listing, you need to add the VIEW service to the SIMPAPP package using the Jolt Repository Editor and write the simpview.c BEA Tuxedo application. This service takes the data from the client VIEW buffer, creates a new buffer and passes it back to the client as a new VIEW buffer. The following example assumes that a session object has already been instantiated.

simpview.java Code Example


/* Copyright 1997 BEA Systems, Inc. All Rights Reserved */
/*
* This code fragment illustrates how Jolt works with a service whose buffer
* type is VIEW.
*/
import bea.jolt.*;
class ...
{
...
public void simpview ()
{
JoltRemoteService ViewSvc;
String outString;
int outInt;
float outFloat;
// Create a Jolt Service for the BEA Tuxedo service "SIMPVIEW"
ViewSvc = new JoltRemoteService("SIMPVIEW",session);
// Set the input parametes required for SIMPVIEW
ViewSvc.setString("inString", "John");
ViewSvc.setInt("inInt", 10);
ViewSvc.setFloat("inFloat", (float)10.0);
// Call the service. No transaction required, so pass
// a "null" parameter
ViewSvc.call(null);
// Process the results
outString = ViewSvc.getStringDef("outString", null);
outInt = ViewSvc.getIntDef("outInt", -1);
outFloat = ViewSvc.getFloatDef("outFloat", (float)-1.0);
// And display them...
System.out.print("outString=" + outString + ",");
System.out.print("outInt=" + outInt + ",");
System.out.println("outFloat=" + outFloat);
}
}


VIEW Field Definitions

The simpview.v16 Field Definitions listing shows the BEA Tuxedo VIEW field definitions for the simpview.java example that were shown in the previous listing.

simpview.v16 Field Definitions


#
# VIEW for SIMPVIEW. This view is used for both input and output. The
# service could also have used separate input and output views.
# The first 3 params are input params, the second 3 are outputs.
#
VIEW SimpView
$
#type cname fbname count flag size null
string inString - 1 - 32 -
long inInt - 1 - - -
float inFloat - 1 - - -
string outString - 1 - 32 -
long outInt - 1 - - -
float outFloat - 1 - - -
END


simpview.c Server Code

In the following listing, the input and output buffers are VIEW. The code accepts the VIEW buffer data as input and outputs the same data as VIEW.

simpview.c Code Example


/*
* SIMPVIEW.c
*
* Copyright (c) 1997 BEA Systems, Inc. All rights reserved
*
* Contains the SIMPVIEW BEA Tuxedo server.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <fml.h>
#include <fml32.h>
#include <Usysflds.h>
#include <atmi.h>
#include <userlog.h>
#include "simpview.h"
/*
* Contents of simpview.h.
*
*struct SimpView {
*
* char inString[32];
* long inInt;
* float inFloat;
* char outString[32];
* long outInt;
* float outFloat;
*};
*/
/*
* service reads in a input view buffer and outputs a view buffer.
*/
void
SIMPVIEW( TPSVCINFO *rqst )
{
/*
* get the structure (VIEWSVC) from the TPSVCINFO structure
*/
struct SimpView *svcinfo = (struct SimpView *) rqst->data;
/*
* print the input params to the UserLog. Note there is
* no error checking here. Normally a SERVER would perform
* some validation of input and return TPFAIL if the input
* is not correct.
*/
(void)userlog("SIMPVIEW: InString=%s,InInt=%d,InFloat=%f",
svcinfo->inString, svcinfo->inInt, svcinfo->inFloat);
/*
* Populate the output fields and send them back to the caller
*/

strcpy (svcinfo->outString, "Return from SIMPVIEW");
svcinfo->outInt = 100;
svcinfo->outFloat = (float) 100.00;
/*
* If there was an error, return TPFAIL
* tpreturn(TPFAIL, ErrorCode, (char *)svcinfo, sizeof (*svcinfo), 0);
*/
tpreturn(TPSUCCESS, 0, (char *)svcinfo, sizeof (*svcinfo), 0);
}