HP3000-L Archives

April 2001, Week 1

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Mike Yawn <[log in to unmask]>
Reply To:
Mike Yawn <[log in to unmask]>
Date:
Tue, 3 Apr 2001 10:17:05 -0500
Content-Type:
text/plain
Parts/Attachments:
text/plain (229 lines)
Hi Dave,

You need to use the Java Invocation API, which is part of JNI, to
create a Java VM.  Then you get a class ID for the class you
want loaded, a method ID for the method you need to invoke,
and call the appropriate JNI call to invoke the method.

I've attached some sample code that does this; this is part of
the never-quite-released VPLUS Class Library for Java.  I've
snipped it heavily since much of the code is duplicated over
and over again for each intrinsic; I've left in the part dealing
with the invocation API and just enough of the rest to let
you follow what's going on (I think).

There's quite a bit more example JNI code available on Jazz
in one of the first tutorials I wrote.  The MPE Class Library
for Java and the TurboIMAGE Class Library for Java, both of
which are downloadable from www.interex.org under the shared
source program, use JNI extensively and can be used as
examples.

Mike

Dave ([log in to unmask]) wrote:
: Hi.

: I'm trying to call some java code from one of our legacy COBOL applications.
: I
: understand that the way to do this is to set up a C stub using the JNI to
: call
: the java, and then to call the C from the COBOL, but I really have no idea
: where to start.

: Does anyone know where I can find an example of this, or does anyone have
: some
: sample code they can let me have?

: Any help would be greatly appreciated. I think my head is about to explode.

: Dave.

: ------------------------------------------------------------
:  Get your FREE web-based e-mail and newsgroup access at:
:                 http://MailAndNews.com

:  Create a new mailbox, or access your existing IMAP4 or
:  POP3 mailbox from anywhere with just a web browser.
: ------------------------------------------------------------


--
-----------------------------------------------------------------
Mike Yawn
Hewlett-Packard                      email       [log in to unmask]
Commercial Systems Division          Phone         (916) 748-3865
8000 Foothills Blvd   MS 5219
Roseville, CA 95747
-----------------------------------------------------------------


/* vpluscalls.c
 *
 * What this is:
 *    This code will go into an XL that will be placed along an
 *  application's linkage path, intercepting any calls to
 *  VPLUS intrinsics.  When the first call (VOPENTERM or VOPENFORMF)
 *  is intercepted, a slaved VM will be created using the
 *  invocation interface (desired enhancement: option to connect to
 *  an existing VM and get a private execution thread).
 *    Each VPLUS call will cause a corresponding Java method in
 *  class com/hp/vplus/VPlusCalls to be called with the same arguments.
 */

#include <jni.h>
#include "comarea.h"

/* Standard invocation API */
static JNIEnv *env;
static JavaVM *jvm;
static int     initialized=0;

/* MPE Extensions to invocation API */
int MPEStackHWM;
int MPEStackLimit;
extern int JavaStackAvail(int);

/* Class, Method, and Field IDs */
static jclass    classString;

static jclass    classVPlus;
static jmethodID methodVChangeField;
static jmethodID methodVCloseFormF; /* XL does part */
static jmethodID methodVCloseTerm;
static jmethodID methodVErrMsg;
static jmethodID methodVFieldEdits;
static jmethodID methodVFinishForm;
/* lots more method ids were here, snipped */

static jclass    classComArea;
static jmethodID methodComAreaInit;
static jmethodID methodGetBufferStatus;
static jmethodID methodGetCFName;
static jmethodID methodGetCMode;
/* lots more method ids were here, snipped */

static jclass    classFieldSpec;
static jmethodID methodFieldSpecInit;

void initIDs(); // forward declaration

#define UPDATE_SHORT(fieldname) \
   ((comarea_type *)comarea)->fieldname = \
      (*env)->CallShortMethod(env, jcomarea, methodGet##fieldname)

#define UPDATE_INT(fieldname) \
   ((comarea_type *)comarea)->fieldname = \
      (*env)->CallIntMethod(env, jcomarea, methodGet##fieldname)

#define UPDATE_STRING(fieldname)                                           \
   {                                                                       \
      jboolean isCopy;                                                     \
      char *contents;                                                      \
      jstring jdata = (jstring)                                            \
             (*env)->CallObjectMethod(env, jcomarea, methodGet##fieldname);\
      contents = (*env)->GetStringUTFChars(env, jdata, &isCopy);           \
      strcpy(contents,((comarea_type *)comarea)->fieldname);               \
   }

/* !! This is the key part !! */

void initialize_vm()
{
   JDK1_1InitArgs vm_args;
   int ret, len;
   char *newcp;

   if (!MPENMStackOK() ) {
      exit(2);
   }

   vm_args.version = 0x00010001;
   JNI_GetDefaultJavaVMInitArgs(&vm_args);

   // Adjust classpath.  This hard-coded path is temporary.
#define MY_CLASSPATH "/YAWN/CLASSLIB/:.:"

   len = strlen(MY_CLASSPATH) + strlen(vm_args.classpath) + 1;
   newcp = (char *)malloc(len);
   strcpy(newcp, MY_CLASSPATH);
   strcat(newcp, vm_args.classpath);
   vm_args.classpath = newcp;

   ret = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
   if (ret < 0) {
      fprintf(stderr, "Can't create JVM.  Error: %d\n", ret);
      exit(2);
   }
   initIDs();
   initialized = 1;
}

void initIDs()
{
   jclass localRef;

   // Initialize Class IDs
   localRef     = (*env)->FindClass(env, "com/hp/vplus/ComArea");
   if (localRef == 0) printf("Bad CID: ComArea\n");
   classComArea = (*env)->NewGlobalRef(env, localRef);

/* more class ids snipped */


   // Initialize Method IDs
   // ComArea
   methodComAreaInit   = (*env)->GetMethodID(env, classComArea,
       "<init>",         "([B)V");
   if (methodComAreaInit == 0) printf("Bad MID: ComArea<init>\n");
   methodGetCFName     = (*env)->GetMethodID(env, classComArea,
       "getCFName",      "()Ljava/lang/String;");
   if (methodGetCFName == 0) printf("Bad MID: getCFName\n");

/* lots more method ids snipped */

}

terminate_vm()
{
   (*jvm)->DestroyJavaVM(jvm);
   initialized = 0;
}

jobject make_jcomarea(char *comarea)
{
   jobject    jcomarea;
   jbyteArray jcomdata;
   jsize      jcomlen = ((comarea_type *)comarea)->ComAreaLen;

   if (!initialized) initialize_vm();

   jcomdata  = (*env)->NewByteArray(env, jcomlen);
   (*env)->SetByteArrayRegion(env, jcomdata, 0, jcomlen, comarea);
   jcomarea  = (*env)->NewObject(env, classComArea, methodComAreaInit,
                                 jcomdata);

   return jcomarea;
}

/* will just show one intrinsic as an example */

void vchangefield(char *comarea, char *specbuffer, short numentries)
{
   jobject jcomarea = make_jcomarea(comarea);
   jobject jspecbuf;
   jbyteArray jspecdata;
   jsize      jbuflen = numentries * 8;  /* 8 bytes per entry */

   jspecdata = (*env)->NewByteArray(env, jbuflen);
   (*env)->SetByteArrayRegion(env, jspecdata, 0, jbuflen,
                              specbuffer);
   jspecbuf = (*env)->NewObject(env, classFieldSpec, methodFieldSpecInit,
                                  jspecdata);

   (*env)->CallStaticVoidMethod(env, classVPlus, methodVChangeField,
           jcomarea, jspecbuf, (jshort) numentries);

   UPDATE_SHORT(CStatus);
}

ATOM RSS1 RSS2