|
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.