View Full Version : Errors in joblog when running "Hello Excel" sample code
I'm getting back-to-back JVAB55A errors when I execute program AIR07_01.
Message . . . . : Parameter received by JNI_CreateJavaVM not valid.
Cause . . . . . : JNI_CreateJavaVM received a parameter that is not valid:
Message ID . . . . . . : JVAB55A Severity . . . . . . . : 40
Date sent . . . . . . : 01/28/10 Time sent . . . . . . : 16:44:2
Message type . . . . . : Diagnostic
CCSID . . . . . . . . : 37
From program . . . . . . . . . : QJVAUTLJVM
From library . . . . . . . . : QSYS
From module . . . . . . . . : QJVAUTLJVM
From procedure . . . . . . . : JvaSendMsg
From statement . . . . . . . : 1391
To program . . . . . . . . . . : SVAIRJAVA
To library . . . . . . . . . : AIRLIB
To module . . . . . . . . . : SVAIRJAVA
To procedure . . . . . . . . : GETJNIENV
To statement . . . . . . . . : 13700
I'm running this on a V5R2 box using Java version 1.4.2. I've used all of the defaults for library and source names. The spreadsheet is correctly created in the default /Public directory.
It seems that the error is issued on the first call to the program, but subsequent calls do not issue the error. Is this something I should be concerned about?
BTW, I'm really enjoying this book so far. Well done Thomas!
01-28-2010, 11:05 PM
You're the first programmer to give me my first critique on my first book! I'm really glad you enjoy the book!
I've been running that code on multiple servers, with multiple OS versions in multiple countries for months without a problem. And son of a gun if I didn't find the problem a few seconds after looking at it!
Replace your getJNIEnv with this one and see if it works. If it does I'll update the download code on the site. If not, let me know and we could try something else.
I believe the problem is here
NEW CODE (CORRECT): rc = JNI_GetDefaultJavaVMInitArgs(%addr(initArgs));
ORIGINAL CODE (INCORRECT): rc = JNI_GetDefaultJavaVMInitArgs(%addr(attachArgs));
in the download. You could just change the parm. Or you could replace the code.
P B EXPORT
D PI *
D rc s LIKE(jint)
D jvm s * DIM(1)
D env s *
D bufLen s LIKE(jsize) INZ(%elem(jvm))
D nVMs s LIKE(jsize)
D initArgs DS LIKEDS(JDK1_1InitArgs)
D attachArgs DS LIKEDS(JDK1_1AttachArgs)
D fd s 10I 0
// First, ensure STDIN, STDOUT, and STDERR are open
fd = IFSOpen('/dev/null': O_RDWR);
if (fd = -1);
// '/dev/null' does not exist in your IFS
// Create it, or use another known good file.
dow ( fd < 2 );
fd = IFSOpen('/dev/null': O_RDWR);
// Second, Attach to existing JVM
// OR Create new JVM if not already running
rc = JNI_GetCreatedJavaVMs(jvm:bufLen:nVMs);
if (rc = 0 and nVMs > 0);
attachArgs = *ALLX'00';
JavaVM_P = jvm(1);
rc = AttachCurrentThread(jvm(1):env:%addr(attachArgs));
initArgs = *ALLX'00';
rc = JNI_GetDefaultJavaVMInitArgs(%addr(initArgs));
if (rc = 0);
rc = JNI_CreateJavaVM(jvm(1):env:%addr(initArgs));
if (rc = 0);
Thanks for the positive feedback. Please let me know if this corrects your problem.
Even though the JVM didn't like the parameters, it still initializes with the default parameters. But, hopefully this should get rid of that error.
I replaced the line of code as indicated and recreated service program SVAIRJAVA. Now I'm getting a completely different error:
Message ID . . . . . . : RNX0301 Severity . . . . . . . : 50
Message type . . . . . : Escape
Date sent . . . . . . : 01/29/10 Time sent . . . . . . : 09:58:37
Message . . . . : Java exception received when calling Java method.
Cause . . . . . : RPG procedure AIR07_01 in program AIRLIB/AIR07_01 received
Java exception "java.lang.NoClassDefFoundError:
org/apache/poi/hssf/usermodel/HSSFWorkbook" when calling method "<init>"
with signature "()V" in class "org.apache.poi.hssf.usermodel.HSSFWorkbook".
Message ID . . . . . . : CEE9901 Severity . . . . . . . : 30
Message type . . . . . : Escape
Date sent . . . . . . : 01/29/10 Time sent . . . . . . : 09:58:50
Message . . . . : Application error. RNX0301 unmonitored by AIR07_01 at
statement 0000003000, instruction X'0000'.
I'm using poi-3.0.2-FINAL-20080204.jar in Public\Java\Excel_POI.
01-29-2010, 09:35 AM
That's strange. Especially since it worked for you before. It's not seeing poi on your classpath. Which is not related to that last change.
Are you signed on as a different user? Do you provide public read access to the folder that the jar resides in and the jar itself.
If authority is not the issue, Could you send me the code you are using as your main in SVAIRJAVA. I'm assuming that you are using the code from the book. But, maybe you have customized is slightly. And could you also call the command WRKLNK, navigate into Public\Java\Excel_POI\ and give me a screen shot of the poi jar file.
I haven't modified the source except to make the change you indicated.
I'm a newbie on this stuff so I'm fairly clueless, but here's some info that is hopefully helpful:
- Before the modification you suggested, if I ran AIR07_01 on a new session I would get the two errors I indicated in the first post. Subsequent calls to the program would not issue the two errors, so that tells me the errors occurred when intializing the JVM.
- I make the suggested modification and recreate the service program. If I call AIR07_01 again from the same session as above, it runs with no errors. This is because it didn't have to initialize the JVM.
- If I run from a new session where the JVM is not started, I get the fatal errors.
In looking at the code we changed, if the return code isn't zero then it looks like it doesn't start the JVM. Is that what could be happening? (I don't know how to debug the service program, so I can't tell.)
I've attached the code after the recommended mod and two screenshots. "location" shows the location of the .jar file and "authority" shows the authority to the .jar file. All folders above that (Public, Java, and Excel_POI) have the same authority.
Let me know if you need anything else.
OK, I figured out how to debug a service program. :)
Here's what I found:
If I use the original code, the first pass through SVAIRJAVA (which is initiated by the first line of code in AIR07_01: CallP JavaServiceProgram()) finds that the JVM is not started so it starts it.
The second pass through SVAIRJAVA (which is initiated by the second line of code in AIR07_01: JNIEnv_P = getJNIEnv()) ALSO finds the JVM not started and so it once again falls through the "start the JVM" code in SVAIRJAVA. This seems weird.
The third call to SVAIRJAVA finally finds the JVM started.
Now using the modified code, the second call to SVAIRJAVA now finds the JVM successfully started.
To sum up: The original code seems to NOT find the JVM started when the second call to SVAIRJAVA is initiated. The modifed code DOES find the JVM started on the second call to SVAIRJAVA, but this is the one that fails. To put another way, the original code doesn't appear to successfully start the JVM on the first invocation of SVAIRJAVA. The modified code does appear to start the JVM on the first invocation of SVAIRJAVA.
01-29-2010, 08:50 PM
Great! You figured out how to debug a service program! I was just going to go into how to do that. For those of you following this forum. You would start debug with STRDBG PGM(AIR07_01) UPDPROD(*YES). Then when you see the source you could hit F14, put a 1 in the opt column, enter SVAIRJAVA in the Program/module column and put *SRVPGM in the Type column. This will add the service program to the list. Put a 5 in from of the *MODULE part of the service program and you'll now see the code for the service program to put in break points and all that.
So, the new getJNIEnv is working as expected. But, when using the new one, you get the error about the class not being found. Just to make sure we're all good with the compiles. Please recompile the module for SVAIRJAVA, then recreate the Service program. After that, recreate the SVAIREXCEL service program. Then finally recompile the AIR07_01 program. This will make sure that everything is up to date.
For some reason I was unable to view the screenshots you presented. I think it has to do with the image viewer in the forum. Could you send them to me? If you go to my profile, you will find my email address.
I had already recompiled everything, but did it again just to be sure but that didn't alter the results.
I didn't see your email address when I viewed your profile. I'm guessing that maybe only you can see it? I sent you a PM on this board with my email address.
I'm going to try this on another V5R2 box that I have access to. I'll report back a little later today with the results. I'm also going to try installing the latest group PTF for Java on my box, but the download from IBM is currently averaging the speed of a crappy 56K modem and so I'm estimating it will take over 5 hours to get it. :( If and when that ever completes I'll let you know if that makes a difference.
Because of how screwy this is behaving (the original code seems to take two passes to enter the initialization routine in the service program but eventually runs OK, where the modified code correctly initializes on the first pass but then bombs out) makes me think that maybe it is a PTF issue. I don't know if running this on the other V5R2 box I have access to will resolve that issue though, because I know for a fact that the Java support on that box was added *after* the latest cum PTF's were installed. Anyway, I'll let you know how it proceeds.
**** Edit ****
OK, I installed on a different V5R2 box and got indentical results. I'll let you know what happens after installing the latest group PTF for Java.
**** Edit 2 ****
No joy. Installing the group PTF for Java made no difference.
Here's a couple of thoughts, although I'm not sure how relevent they are:
When I check the Java version using the 'java -version' command under QShell, it tells me that the default version is 1.3.1. I did some research on this and found that you could specify the default version by placing a 'SystemDefault.properties' file in the QIBM\UserData\Java400 directory and entering the version you want as the default. I did that and now the default version is reported as 1.4.2. But, further research indicated that if you start the JVM using the 'JNI_CreateJavaVM' function in a version prior to V5R3, then the 'SystemDefault.properties' is ignored and you need to set the enviornment variable using the QIBM_RPG_JAVA_PROPERTIES indicating which version you want to use. I tried doing this in a CL program by executing command "ADDENVVAR ENVVAR(QIBM_RPG_JAVA_PROPERTIES) VALUE('-Djava.version=1.4;') REPLACE(*YES)" prior to calling AIR07_01, but that didn't work either. Still, I feel like this may be part of the problem. Is there a way for me to tell which version of Java AIR07_01 is using?
I just wanted to report back that with Tom Snyders help, this problem has been solved. The problem is related to how you specify which JVM to use in releases prior to V5R3. Tom was able to provide code changes that address these differences. Many thanks to Tom for his diligence in quickly finding a solution to this problem.
02-04-2010, 05:53 PM
You're very welcome. I'm glad I was able to help you out and it was a pleasure working with you!
Time to share the wealth of information that we've found.
There were two problems that were caused with V5R2:
<h2>Selecting the correct JVM</h2>
The first problem was that there were multiple versions of Java installed on the IBM i and it was not using the one that we wanted. The versions installed were 1.1.8, 1.3.1 and 1.4.2. We wanted 1.4.2 and it was using 1.1.8.
<b>We tried all of the usual methods:</b>
<li>"ADDENVVAR ENVVAR(QIBM_RPG_JAVA_PROPERTIES) VALUE('-Djava.version=1.4;') REPLACE(*YES)"
<li>Setting the JVM in /QIBM/UserData/Java400/SystemDefault.properties
<li>And passing in the requested version when starting up the JVM
All with no luck.
The answer was to update the getJNIEnv procedure to use the likeDs(JavaVMInitArgs) instead of the original LIKEDS(JDK1_1InitArgs) data structure to declare our initArgs that were used with JNI_CreateJavaVM which allowed us to specify the JNI version to be used when starting up the JVM.
The funny thing is that when we specified JNI_VERSION_1_4 (x'00010004') it started up 1.3.1? So I boosted the JNI to JNI_VERSION_1_6(x'00010006') which forced it to use the JVM specified in the /QIBM/UserData/Java400/SystemDefault.properties file and then it started using the intended JVM 1.4.2. Success!
<h2>Setting the Classpath</h2>
Once we got that worked out, we still had an issue because, even though the classpath was set correctly prior to starting the JVM, it reset back when the JVM was started.
<b>Tried the usual methods:</b>
<li>ADDENVVAR ENVVAR(CLASSPATH) '
+ ''') REPLACE(*YES)';
<li>Passing in the classpath on the JVM initialization
All with no luck.
<b>There are two solutions to this problem:</b>
<li>Place the external jars intended to be used into the /QIBM/UserData/Java400/ext folder
<li>Specify the classpath in /QIBM/UserData/Java400/SystemDefault.properties
So, if you are using V5R3 or V5R4 when using the code in the book, you will work fine as is. If you are working on V5R2 then this information should get you running!
I will post an update to the code that should be available in the next few days. In the SVAIRJAVA code I will put a note in the header saying something like "Version 2.0, with new getJNIEnv procedure" so look for that if you're looking for the new code to get you past the hurdles on V5R2. Actually, even if you're not using V5R2, you may want to pick up the new code which includes some additional procedures to view the currently running version and classpath.
Thanks and Have Fun Coding!
Powered by vBulletin® Version 4.1.5 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.