× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Sorry for opening old wounds (and the lengthy post) but...if you're one
of the many who participated previously......

Various posts have discussed how to "catch" or "monitor" java errors in
RPG applications.  As suggestions ranged from simply using the MONITOR
opcode
to setting Environment variables, I thought I'd share another option.

First, as Barbara Morris suggests in the following post:

http://archive.midrange.com/rpg400-l/200309/msg00071.html

There does appear to be a limitation in the RPG/Java interface where
exceptions
are not "thrown" to STDERR.  While Barbara suggests the future possibility
of
adding an environment variable triggering the RPG runtime to call the JNI's
"ExceptionDescribe" function, I would opt to have this as the default
behavior
verses adding yet another environment variable.  Just my 2 cents...

Secondly, there are java methods that, even when called by the RPG runtime,
do
"throw" errors to STDERR (by default).  Some that I use regularly are in
IBM's
MQSeries Java classes.  In lieu of direct RPG calls, you could use the JNI
to
invoke java methods verses traditionally prototyped method calls.  This then
provides the option to "throw" errors to STDERR via "ExceptionDescribe".
While
this may provide a layer of granularity in error handling, it does require a
fair
amount of extra coding.

Next, none of the above enables your RPG application to directly access
STDERR.
While previous posts on this topic have demonstrated how, using an
environment
variable, you can redirect STDERR output to an IFS file, this technique also
inclusively redirects STDOUT.  If you don't insert the "os400.stdout=file:"
entry in your SystemDefault.properties file, STDOUT output vanishes.  As
this
approach also assigns STDERR & STDOUT redirection for the system or session,
this may not be desirable at a particular application level (no to mention
any IFS housekeeping). 

In an effort to provide some sense of error handling granularity in RPG, I
prefer
to use a java technique that is reminiscent of re-directing S/38 command
output to
QTEMP (S/38 programmers probably remember those days prior to IBM adding all
the
API functions).

Starting with JDK 1.2, java provides the "java.io.File.createTempFile"
method.  This
allows java applications to create a work file in the "/tmp" directory.
Additionally,
it allows the application to specify predefined "prefix" & "suffix" values
for the
file.  When specifying a NULL suffix value, the suffix defaults to ".tmp".
For STDERR
files (createTempFile serves more than STDERR) I prefer to use the prefix of
"STDERR",
thus temporary files are named in the form of "STDERRnnnnn.txt".  Also for
STDERR,
I recommend combining the "createTempFile" call with a
"java.io.File.deleteOnExit"
call.  This instructs the JVM to dynamically purge your temporary file when
the JVM
(not your program) ends.  Once you've constructed (and retrieved the label
of) your
temporary file, you can use the "java.lang.System.setErr" method to redirect
all
"thrown" STDERR output to your file.

Well that takes care of redirecting STDERR output, but what how does that
provide
my RPG program access to the errors?  Simple.  You associate your STDERR
file with
Input Stream, Reader and Buffer handles for later reading.  There are no
restrictions
against "reading" STDERR.  For simplicity and re-use, I encapsulate the
creation and
reading of STDERR in subprocedures.  

Assume the following snippet has successfully created and redirected STDERR
to a
temporary file.  In addition, corresponding stream, reader and buffer
handles have been
established with STDERR.

Where:

Thingclass = java.lang.Class (Object)
JLT = 'java/lang/Thing' ASCII signature
JNIEnv_P = Pointer to JVM
JNI_Error = 'java.lang.Throwable' (Object)
errmsg = 'java.lang.String' (Object)

Using the JNI to invoke a non-existent method called "java.lang.Thing":

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                                            

results in execution of subprocedure JavaErr:

P JavaErr         B                                              
D JavaErr         PI                                             
 *                                                               
C                   dou       errmsg = *NULL                     
 *                                                               
C                   Monitor                                      
C                   eval      errmsg = readLine(Buff_Reader)     
 *                                                               
C                   if        errmsg = *NULL                     
C                   ITER                                         
C                   endif                                        
 *                                          (java.lang.String.length)

C                   EVAL      String_long = GetStringLng(errmsg) 
C                   on-error                                     
C                   ITER                                         
C                   endmon                                       
 *                                                               
C                   eval      text = *BLANKS                     
 * convert Java string to character (java.lang.String.getBytes)

C                   callp     GetStringChar(errmsg:0:String_long:
C                             text:0)
 *                                                        
C                   enddo                                 
 *                                                        
P JavaErr         E


Because 2 STDERR entries are "thrown", field "text" would contain:

java.lang.NoClassDefFoundError: java/lang/Thing

then:                            
      java/lang/Throwable.<init>(Ljava/lang/String;)V+4 (Throwable.java:94)

Unfortunately, defining a prototype for the "java.lang.Thing" method fails
to provide any feedback to STDERR or your RPG program (except RNX0301).
This,
I suspect, is what Barbara Morris described in the a fore mentioned post.

Lastly, this approach may not be as flexible as using "catch" in Java,
however,
it does provide RPG programmers with some ability for monitoring errors
encountered
when invoking java methods from your RPG program.

Michael Rooney
CitiGroup International
Tampa, Florida

P.S.

If there is still enough interest on this topic, I will post a sample
program demonstrating
the entire technique.      

   

   


          
        




  
    

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 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.