RPG calling Java, java.lang.NoClassDefFoundError

5.6k views Asked by At

My aim is to call a Web Service from Java, initiated from a RPG function. (I know, its long way around, but it is what we need)

I have created a /JavaLib folder on the AS400, and copied all our needed External Jars we need.

Create a Java class with a static method WebServiceCaller.Call() to call a Web Service. When ever I run my RPG program everything is fine unto the RPG calls this method.

I get a Java exception:

Message . . . . : Java exception received when calling Java method (C G D F).
Cause . . . . . : RPG procedure WEBSERCALR in program WAL60326/WEBSERCALR received Java exception "java.lang.NoClassDefFoundError:
javax.xml.rpc.ServiceException" when calling method "Call" with signature "(LwebService.Input;)LwebService.Output;" in class
"webService.WebServiceCaller".

CLASSPATH variable:

/JavaLib:/home/WAL60326/WebServiceCaller

So I believe my RPG and Java Class is fine, and I believe I have setup my CLASSPATH variable right. Not sure what else there is to check.


Update

So the jar file I need is jaxrpc.jar I have checked; it does exists in my /JavaLib. Was able to check my Java version on the AS400 java version "1.5.0". And follow these instructions to check that my OS is V6R1.

Could it be my Java version that is out of date, for this Jar file to be loaded/work? Is that even a possibility?


Edit

Here is my source code:

Java: WebServiceCaller.Java

package webService;

import java.rmi.RemoteException;

import stocklistGetBids.GetBidsProxy;

public class WebServiceCaller {
    public static Output Call(Input in) { // Input Class, is just a way to hold all the input together
        Output out = null; // Output Class, holds all the output together

        try {
            GetBidsProxy getBidsProxy = new GetBidsProxy(); // GetBidsProxy generated by Eclipse 

            out = new Output(getBidsProxy.getBids(in.LogKey, in.Id));           

        } catch (RemoteException e) {
            e.printStackTrace();
            out = new Output("ERR"); 
        }

        return out;
    }
}

Take note that the GetBidsProxy class in generated by Eclipse. And the Java side works well on my Windows Machine. Just not on the AS400 Machine.

RPG: WEBSERCALR.RPGLE

 H DFTACTGRP(*NO)
 H thread(*serialize)

 D WebsercalInput  DS
 D   ReturnCode                   7A
 D   LogKey                      20A
 D   ID                          20A

 D jString         S               O   CLASS(*JAVA:'java.lang.String')
 D jLogKey         S               O   CLASS(*JAVA:'java.lang.String')
 D jID             S               O   CLASS(*JAVA:'java.lang.String')
 D Input           S               O   CLASS(*JAVA:'webService.Input')
 D Output          S               O   CLASS(*JAVA:'webService.Output')

 D new_Input       PR              O   EXTPROC(*JAVA:
 D                                       'webService.Input':
 D                                       *CONSTRUCTOR)
 D   LogKey                            like(jString)
 D   ID                                like(jString)

 D new_String      PR              O    EXTPROC(*JAVA:
 D                                       'java.lang.String':
 D                                       *CONSTRUCTOR)
 D  bytes                        30A    CONST VARYING

 D Call            PR                  like(Output)
 D                                     EXTPROC(*JAVA:
 D                                       'webService.WebServiceCaller':
 D                                       'Call')
 D                                     STATIC
 D  in                                 like(Input)

 D getReturnStat   PR              O   EXTPROC(*JAVA:
 D                                       'webService.Output':
 D                                       'getReturnedStatus')
 D                                     CLASS(*JAVA:'java.lang.String')

 D getBytes        PR         65535A   VARYING
 D                                     EXTPROC(*JAVA:
 D                                       'java.lang.String':
 D                                       'getBytes')

 C     *ENTRY        PLIST
 C                   PARM                    WebsercalInput

  /free
   jLogKey = new_String(LogKey);
   jID = new_String(ID);

   Input = new_Input(jLogKey:jID);

   Output = Call(Input);

   jString = getReturnStat(Output);

   ReturnCode = getBytes(jString);

   return;
  /End-Free
3

There are 3 answers

1
Buck Calabro On

The CLASSPATH is read only once for a given job, the first time you invoke the java command and the JVM starts. If your CLASSPATH changes after that, the JVM won't see or use the new CLASSPATH. Sign off and on (to start a new job), set the CLASSPATH (I do it in my signon program) and then try to use the class you're working with.

1
Buck Calabro On

If the CLASSPATH is correct then the other thing to check is the Java prototype in your RPG program. It needs to exactly match the Java class definition.

First, make 100% certain that your jaxrpc.jar has all the classes you think it should. Start QShell, then java tf /JavaLib/jaxrpc.jar. Make sure you have at least these:

javax/xml/rpc/Call.class             
javax/xml/rpc/ServiceFactory.class   
javax/xml/rpc/ServiceException.class 

Next, do a simple proof of concept program in pure Java to make sure all of the pieces work as you expect them to. Note: JAX-RPC is obsolete and goes away in Java 1.6 and up. It's been replaced by JAX-WS. If this is a brand new app, consider using the more current implementation. This 2006 DeveloperWorks article explains some of the differences.

Once you have a pure Java program written, it's time to take the Java classes that you used and prototype them in RPG. Assuming you've done all of that, could you edit your question to show the RPG *CLASS prototypes and the RPG code used to invoke them. Basically, see if someone reading this question can re-create the set-up on a different box.

0
user3137978 On

I've used some Java in my RPG code and I found out that it's not enough to add the container folder to the CLASSPATH. I had to identify the individual jars in the CLASSPATH.