|
Here's sample TSTJAVAERR demonstrating how to monitor/catch java errors
in RPG via STDERR.....
*********************************************************************
* *
* Description: Simple program demonstrating how to "trap" and/or *
* monitor Java errors in an RPG program. *
* *
* Notes: On my system I package working java & JNI prototypes *
* into various source files in a library named *
* QRPGJAVA. The file naming scheme is derived *
* from the java class. For example, the constructor *
* for java.lang.String would be found in member *
* "newstring" in file QRPGJAVA/Lang. Prototypes *
* for java.io methods are in file "IO" and so forth. *
* I've included all /COPY (ex. JNI) members for *
* simplicity. *
* *
*********************************************************************
H THREAD(*SERIALIZE) BndDir('QC2LE') DFTACTGRP(*NO) ACTGRP(*NEW)
*
* Requires JVM 1.2.x or higher
D/DEFINE OS400_JVM_12
*
D/DEFINE JNI_COPY_FIELD_FUNCTIONS
D/COPY qsysinc/QRPGLESRC,JNI
******************************************************************
* Retrieve string representation of java File Object
******************************************************************
D*COPY qrpgjava/io,tostring
DtoString PR O EXTPROC(*JAVA:'java.io.File':
D 'toString')
D CLASS(*JAVA:'java.lang.String')
******************************************************************
* Retrieve JVM property
******************************************************************
D*COPY qrpgjava/lang,getproprty
DGetJVMProp PR O EXTPROC(*JAVA:'java.lang.System':
D 'getProperty') STATIC
D CLASS(*JAVA:'java.lang.String')
D property O CLASS(*JAVA:'java.lang.String')
D CONST
******************************************************************
* Retrieve length of string
******************************************************************
D*COPY qrpgjava/lang,getstrlong
DGetStringLng PR 10I 0 EXTPROC(*JAVA:'java.lang.String':
D 'length')
******************************************************************
* Set Temp File to be "deleted" at EOJ
******************************************************************
D*COPY qrpgjava/io,dltonexit
DDltOnExit PR EXTPROC(*JAVA:'java.io.File':
D 'deleteOnExit')
******************************************************************
* Redirect STDERR output to a file
******************************************************************
D*COPY qrpgjava/lang,setSTDErr
DSetErr PR EXTPROC(*JAVA:'java.lang.System':
D 'setErr') STATIC
D Filehandle O CLASS(*JAVA:
D 'java.io.PrintStream')
******************************************************************
* Convert Java string to characters
******************************************************************
D*COPY qrpgjava/lang,getstrchar
DGetStringChar PR EXTPROC(*JAVA:'java.lang.String':
D 'getBytes')
D SrcBegin 10I 0 value
D SrcEnd 10I 0 value
D Destination 300A
D DestBegin 10I 0 value
******************************************************************
* Create Java File Input Stream Object
******************************************************************
D*COPY qrpgjava/io,filInpStrm
DIStream PR O EXTPROC(*JAVA:
D 'java.io.FileInputStream':
D *CONSTRUCTOR)
D CLASS(*JAVA:
D 'java.io.FileInputStream')
D FileHandle O CLASS(*JAVA:
D 'java.io.File')
******************************************************************
* Create Java PrintStream Object
******************************************************************
D*COPY qrpgjava/io,PrtStream
DPrintStream PR O EXTPROC(*JAVA:
D 'java.io.PrintStream':
D *CONSTRUCTOR)
D CLASS(*JAVA:
D 'java.io.PrintStream')
D StreamHandle O CLASS(*JAVA:
D 'java.io.OutputStream')
******************************************************************
* Create Java Input Stream Reader Object
******************************************************************
D*COPY qrpgjava/io,IStrmRdr
DIStreamRdr PR O EXTPROC(*JAVA:
D 'java.io.InputStreamReader':
D *CONSTRUCTOR)
D CLASS(*JAVA:
D 'java.io.InputStreamReader')
D IStreamHandle O CLASS(*JAVA:
D 'java.io.InputStream')
******************************************************************
* Create Java BufferedReader Object
******************************************************************
D*COPY qrpgjava/io,readLine
DreadLine PR O EXTPROC(*JAVA:
D 'java.io.BufferedReader':
D 'readLine')
D CLASS(*JAVA:
D 'java.lang.String')
******************************************************************
* Create Java BufferedReader Object
******************************************************************
D*COPY qrpgjava/io,BuferedRdr
DBufferedRdr PR O EXTPROC(*JAVA:
D 'java.io.BufferedReader':
D *CONSTRUCTOR)
D CLASS(*JAVA:
D 'java.io.BufferedReader')
D StreamHandle O CLASS(*JAVA:
D 'java.io.Reader')
******************************************************************
* Create Java Output Stream Object
******************************************************************
D*COPY qrpgjava/io,filOutStrm
DOStream PR O EXTPROC(*JAVA:
D 'java.io.FileOutputStream':
D *CONSTRUCTOR)
D CLASS(*JAVA:
D 'java.io.FileOutputStream')
D FileHandle O CLASS(*JAVA:'java.lang.String')
D append N value
******************************************************************
* Create Java Temporary File Object
******************************************************************
D*COPY qrpgjava/io,CrtTmpFile
DcrtTmpFile PR O EXTPROC(*JAVA:'java.io.File':
D 'createTempFile') STATIC
D CLASS(*JAVA:
D 'java.io.File')
D FilePrefix O CLASS(*JAVA:'java.lang.String')
D CONST
D FileSuffix O CLASS(*JAVA:'java.lang.String')
D CONST
******************************************************************
** String Constructor **
******************************************************************
D*COPY qrpgjava/lang,NewString
Dnewstring PR O EXTPROC(*JAVA:
D 'java.lang.String':
D *CONSTRUCTOR)
D CLASS(*JAVA:'java.lang.String')
D 48A varying CONST
******************************************************************
** Integre Constructor (doesn't exist!) **
******************************************************************
Dnewinteger PR O EXTPROC(*JAVA:
D 'java.lang.Integre':
D *CONSTRUCTOR)
D CLASS(*JAVA:'java.lang.Integre')
D integer 10I 0 value
******************************************************************
*
******************************************************************
D Init PR N
D JavaErr PR
*
D printf PR EXTPROC('printf')
D * value options(*string)
***************************************************************
* Define our Java Class objects and signatures for JNI calls.
***************************************************************
DStringClass S O CLASS(*JAVA:'java.lang.Class')
* 'java/lang/String' signature
DJLS C x'6a6176612f6c616e672f-
D 537472696e67'
DThingClass S O CLASS(*JAVA:'java.lang.Class')
* 'java/lang/Thing' signature
DJLT C x'6a6176612f6c616e672f-
D 5468696e67'
**************************************************
* Define Java objects
**************************************************
Derrmsg S O CLASS(*JAVA:'java.lang.String')
DJVM_Ver S O CLASS(*JAVA:'java.lang.String')
DBuff_Reader S O
CLASS(*JAVA:'java.io.BufferedReader')
DIStreamReader S O CLASS(*JAVA:
D 'java.io.InputStreamReader')
DFileIn S O CLASS(*JAVA:
D 'java.io.FileInputStream')
DErrorLog S O CLASS(*JAVA:'java.lang.String')
DPS S O
CLASS(*JAVA:'java.io.PrintStream')
DErrorf_handle S O
CLASS(*JAVA:'java.io.OutputStream')
DErrFile S O CLASS(*JAVA:'java.io.File')
Dsuffix S O CLASS(*JAVA:'java.lang.String')
DJNI_Error S O CLASS(*JAVA:
D 'java.lang.Throwable')
Dten_java S O CLASS(*JAVA:'java.lang.Integer')
**************************************************
* Miscellaneous fields and prototypes
**************************************************
Dten_int S 10I 0 inz(10)
Dstring_long S 10I 0
*
Dtext S 300
Dappend S N inz(*ON)
*
DgetJniEnv PR *
DdestroyJVM PR N
************************************************************
*
************************************************************
* Call INIT to launch JVM and redirect STDERR.
C EVAL *inlr = init()
C if *inlr = *ON
C return
C endif
*
C callp Printf('Calling java.lang.Intgre '
+
C 'class....' + x'15')
C monitor
C eval ten_java = newInteger(ten_int)
C on-error
C callp JavaErr
C endmon
*
C callp Printf('Finding java.lang.String '
+
C 'class....' + x'15')
C eval Stringclass = FindClass (JNIEnv_P:JLS)
C EVAL JNI_error = ExceptionOccurred(JNIEnv_P)
C if JNI_error <> *NULL
C callp ExceptionDescribe(JNIEnv_P)
C callp ExceptionClear(JNIEnv_P)
C callp JavaErr
C endif
*
C callp Printf('Finding java.lang.Thing '
+
C 'class....' + x'15')
C eval Thingclass = FindClass (JNIEnv_P:JLT)
C EVAL JNI_error = ExceptionOccurred(JNIEnv_P)
C if JNI_error <> *NULL
C callp ExceptionDescribe(JNIEnv_P)
C callp ExceptionClear(JNIEnv_P)
C callp JavaErr
C endif
*
C move '1' *inlr
*
C callp destroyJVM()
**************************************************************
*
**************************************************************
P Init B
D Init PI N
************************************************************
* Start JVM or Retrieve Pointer to active JVM
************************************************************
C move '0' *INLR
C eval JNIEnv_P = getJniEnv()
* Retrieve JVM Version (use "errmsg" object just because....)
C EVAL errmsg = newString('java.version')
**************************************************************
* Retrive JVM version for 2 reasons:
* 1 - Display JVM version to demonstrate program is running
* 2 - method 'crtTmpFile' not available before 1.2
* --> One such error this technique can't monitor!!
**************************************************************
C EVAL JVM_Ver = GetJVMProp(errmsg)
C EVAL String_long = GetStringLng(JVM_Ver)
* convert Java string to character and display JVM Version
C callp GetStringChar(JVM_Ver:0:String_long:
C text:0)
C callp Printf(%trimr(text) + x'15')
*
C EVAL errmsg = newString(' ')
C EVAL Errorlog = newString('STDERR')
C EVAL suffix = *NULL
C monitor
* Create temporary STDERR outfile for OUR process.
C EVAL ErrFile = crtTmpFile(Errorlog : suffix)
C on-error
* crtTmpFile not available prior to JVM 1.2.
C callp Printf('Error calling "crtTmpFile". Che'
+
C 'ck JVM version.' + x'15')
C move '1' *INLR
C return *INLR
C endmon
* Set our STDERR outfile to be deleted when process ends.
C callp DltOnExit(ErrFile)
* Convert actual name of temporary STDERR file to java string.
C EVAL Errorlog = toString(ErrFile)
* Create Output Stream to our STDERR file
C EVAL Errorf_Handle = OStream(Errorlog:append)
C EVAL PS = PrintStream(Errorf_handle)
* Force all STDERR output to our file in /tmp.
C callp SetErr(PS)
**************************************************************
* Prepare our temp file for input processing.
**************************************************************
* Create Input Stream to our STDERR file so we can read.
C EVAL FileIn = IStream(ErrFile)
* Attach to Input Stream "reader"
C EVAL IStreamReader = IStreamRdr(FileIn)
* Link to Buffered reader.
C EVAL Buff_Reader = BufferedRdr(IStreamReader)
*
C return *INLR
P Init E
**************************************************************
*
**************************************************************
P JavaErr B
D JavaErr PI
*
C callp Printf('Routine JavaErr entered' + x'15')
*
C dou errmsg = *NULL
*
C Monitor
C eval errmsg = readLine(Buff_Reader)
*
C if errmsg = *NULL
C callp Printf('No more Messages in STDERR' +
x'15')
C ITER
C endif
*
C EVAL String_long = GetStringLng(errmsg)
C on-error
C ITER
C endmon
*
C eval text = *BLANKS
* convert Java string to character
C callp GetStringChar(errmsg:0:String_long:
C text:0)
* Display the error message
C callp Printf(%trimr(text) + x'15')
*
C enddo
*
P JavaErr E
*
D*COPY ROONEY/QRPGLESRC,getJniEnv
********************************************************************
* Procedure - getJniEnv
*
* Implemented OS400_JVM_11 directive to facilitate invocation
* of 1.1.8 JVM on request ONLY, not by default.
********************************************************************
p getJniEnv B EXPORT
d getJniEnv PI *
d rc S LIKE(jint)
d rpgRc S N
d jvm S * DIM(1)
d env S *
d bufLen S LIKE(jsize) INZ(%elem(jvm))
d nVMs S LIKE(jsize)
/if not defined(OS400_JVM_11)
d initArgs DS LIKEDS(JavaVMInitArgs)
d attachArgs DS LIKEDS(JavaVMAttachArgs)
D singleOption DS LIKEDS(JavaVMOption)
/ELSE
D initArgs DS LIKEDS(JDK1_1InitArgs)
D attachArgs DS LIKEDS(JDK1_1AttachArgs)
/ENDIF
* '-verbose:jni'
D verbose S 12 inz(x'2d766572626f73653a6a6e69')
* '-Djava.version=1.1.8'
D JDK_11 S 20
inz(x'2d446a6176612e76657273696f6e-
D 3d312e312e38')
* '-Djava.version=1.2'
D JDK_12 S 18
inz(x'2d446a6176612e76657273696f6e-
D 3d312e32')
/free
//-------------------------------------------------------------
// See if there's a JVM started
//----------------------------------------------------------- -
rc = JNI_GetCreatedJavaVMs (jvm : bufLen : nVMs);
//-------------------------------------------------------------
// If JVM is started, just attach to it, to get the env pointer
//-------------------------------------------------------------
if (rc = 0 and nVMs > 0);
attachArgs = *ALLX'00';
/if defined(OS400_JVM_12)
attachArgs.version = JNI_VERSION_1_2;
/endif
JavaVM_P = jvm(1);
rc = AttachCurrentThread (jvm(1): env : %addr(attachArgs));
//----------------------------------------------------------- -
// If JVM is not started, start it
//-------------------------------------------------------------
else;
/if not defined(OS400_JVM_11)
singleOption.optionString = %addr(JDK_12);
singleOption.extraInfo = *NULL;
/endif
/if defined(OS400_JVM_11)
// initArgs.reserved0 = JNI_VERSION_1_1;
initArgs.reserved0 = x'00010001';
/else
initArgs.version = JNI_VERSION_1_2;
initArgs.nOptions = 1;
initArgs.options = %addr(singleOption);
initArgs.ignoreUnrecognized = JNI_FALSE;
/endif
rc = JNI_CreateJavaVM (jvm(1) : env : %addr(initArgs));
// dump(a);
endif;
if (rc = 0);
return env;
else;
return *NULL;
endif;
/end-free
P getJniEnv E
D*COPY ROONEY/QRPGLESRC,destroyJVM
P destroyJVM B EXPORT
D destroyJVM PI N
D rc S LIKE(jint)
D rpgRc S N
D jvm S * DIM(1)
D env S *
D bufLen S LIKE(jsize) INZ(%elem(jvm))
D nVMs S LIKE(jsize)
/free
//----------------------------------
// See if there's a JVM started
//----------------------------------
rc = JNI_GetCreatedJavaVMs (jvm : bufLen : nVMs);
// dump(a);
//----------------------------------
// If JVM is started, destroy it!
//----------------------------------
if (rc = 0)
and (nVMs >0);
JavaVM_P = jvm(1);
rc = DestroyJavaVM (jvm(1));
// dump(a);
endif;
if (rc = 0);
return *ON;
else;
return *OFF;
endif;
/end-free
P destroyJVM E
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.