RPG chiamata Java, java.lang.NoClassDefFoundError
Il mio obiettivo è chiamare un servizio Web da Java, avviato da una funzione RPG. (Lo so, la sua lunga strada intorno, ma è quello che ci serve)
Ho creato una cartella /JavaLib
sull'AS400 e ho copiato tutti i nostri jar esterni necessari di cui abbiamo bisogno.
Creare una classe Java con un metodo statico WebServiceCaller.Call()
per chiamare un servizio Web. Quando mai corro il mio programma RPG tutto va bene fino al RPG chiama questo metodo.
Ottengo un'eccezione Java:
Messaggio . . . . : Eccezione Java ricevuto quando si chiama il metodo Java (C G D F).
Causare . . . . . : Procedura RPG WEBSERCALR nel programma WAL60326 / WEBSERCALR eccezione Java ricevuta " java.lang.NoClassDefFoundError:
javax.XML.rpc.ServiceException "quando si chiama il metodo "Chiama" con la firma "(LwebService.Ingresso;)LwebService.Output; " nella classe
"webService.WebServiceCaller".
Variabile CLASSPATH:
Per maggiori informazioni clicca qui]}
Quindi Credo che la mia classe RPG e Java vada bene, e credo di aver impostato correttamente la mia variabile CLASSPATH. Non sono sicuro di cos'altro c'è da controllare.
Aggiornare
Quindi il file jar di cui ho bisogno è jaxrpc.jar
che ho controllato; esiste nel mio /JavaLib
.
È stato in grado di controllare la mia versione Java su AS400 java version "1.5.0"
. E segui queste istruzioni per verificare che il mio sistema operativo sia V6R1.
Potrebbe essere la mia versione Java non aggiornata, per caricare/lavorare questo file Jar? E almeno un possibilità?
Modifica
Ecco il mio codice sorgente:
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;
}
}
Prendere atto che la classe GetBidsProxy in generato da Eclipse. E il lato Java funziona bene sulla mia macchina Windows. Ma non sulla macchina AS400.
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 answers
Il CLASSPATH viene letto una sola volta per un determinato lavoro, la prima volta che si richiama il comando java e la JVM viene avviata. Se il tuo CLASSPATH cambia dopo, la JVM non vedrà o utilizzerà il nuovo CLASSPATH. Disconnetti e attiva (per iniziare un nuovo lavoro), imposta il CLASSPATH (lo faccio nel mio programma signon) e quindi prova a utilizzare la classe con cui stai lavorando.
Se il CLASSPATH è corretto, l'altra cosa da controllare è il prototipo Java nel tuo programma RPG. Deve corrispondere esattamente alla definizione della classe Java.
Innanzitutto, assicurati al 100% che il tuo jaxrpc.jar ha tutte le classi che pensi che dovrebbe. Avviare QShell, quindi java tf /JavaLib/jaxrpc.jar
. Assicurati di avere almeno questi:
javax/xml/rpc/Call.class
javax/xml/rpc/ServiceFactory.class
javax/xml/rpc/ServiceException.class
Quindi, fai un semplice programma proof of concept in puro Java per assicurarti che tutti i pezzi funzionino come ti aspetti. Nota: JAX-RPC è obsoleto e va via in Java 1.6 e versioni successive. È stato sostituito da JAX-WS. Se si tratta di una nuova applicazione, considerare l'utilizzo dell'implementazione più attuale. Questo articolo di 2006 DeveloperWorks spiega alcune delle differenze.
Una volta che hai scritto un programma Java puro, è il momento di prendere le classi Java che hai usato e prototiparle in RPG. Supponendo che tu abbia fatto tutto questo, potresti modificare la tua domanda per mostrare i prototipi di CLASSE RPG *e il codice RPG usato per invocarli. Fondamentalmente, vedere se qualcuno la lettura di questa domanda può ricreare il set-up su una scatola diversa.
Ho usato un po ' di Java nel mio codice RPG e ho scoperto che non è sufficiente aggiungere la cartella del contenitore al CLASSPATH. Ho dovuto identificare i singoli vasi nel CLASSPATH.