PDA

View Full Version : Aufruf Java-Klasse aus RPGLE



stefan24
24-02-12, 08:44
Hallo zusammen..

Ich versuche im Moment vezweifelt eine Java-Methode direkt aus einem RPGLE-PGM aufzurufen. Leider mit sehr besch.. eidenem Erfolg. Vieleicht kann mir jemand zu folgendem Konstrukt einen Tip geben..

Definition im RPG:


* Methode zum Signieren
d getSignature PR O EXTPROC(*JAVA:
d 'app.tools.GenSign':
d 'getSignature')
d CLASS(*JAVA:'java.lang.String')
d STATIC
d text O CLASS(*JAVA:'java.lang.String')

* Erstellen String-Objekt aus Textfeld
d crtString PR O EXTPROC(*JAVA:
d 'java.lang.String':
d *CONSTRUCTOR)
d Class(*JAVA:'java.lang.String')
d bytes 255A Const Varying


Die Java-Klasse GenSign, in welcher die Methode getSignature angesprochen werden soll liegt in einem jar-File (test.jar). Der entsprechende CLASSPATH wird (vorerst mal zum Test) über eine interne Variable gesetzt:


D testCP S 255A varying
D inz('/test1/test/test.jar') Der CLASSPATH wird dann hier entsprechend gesetzt:


// -------------------------------------------------------------
// sr fix_classpath = Verzeichnis der aufzurufenden Java-Klasse
// einstellen
// -------------------------------------------------------------
begsr fix_classpath;

ClassPath = getEnvVar('Classpath');
if Classpath = '';
Classpath = '.:';
endif;
fnd = %scan(testCP:ClassPath);
if fnd <= 0;
setEnvVar('Classpath=' +
classPath +
%trim(testCP) + ':');
endif;
ClassPath = getEnvVar('Classpath'); // fuer Debug

endsr; Bei Aufruf des Programms (CALL TESTPGM '123456789') wird der entry-parameter vorerst über crtString konvertiert (funktioniert) und dann an die besagte Methode aus GenSign übergeben (getSignature) ..



exsr fix_classpath;

datain = crtString(inout); // Var -> String[]
dataout = getSignature(datain); // Signatur erstellen
inout = getBytes(dataout); // String[] -> Var

*inlr = *on;
return; .. dann kommt folgender Fehler:

Weitere Nachrichteninformationen

Nachrichten-ID . . . . : RNX0301 Bewertung . . . . . . : 50
Nachrichtenart . . . . : Diagnose
Sendedatum . . . . . . : 24.02.12 Sendezeit . . . . . . : 09:41:23

Nachricht . . . : Java-Ausnahme beim Aufrufen der Java-Methode empfangen.
Ursache . . . . : RPG-Prozedur TESTPGM in Programm XYZ/TESTPGM hat
Java-Ausnahme "java.lang.NoClassDefFoundError: app/tools/GenSign"
empfangen, als die Methode "getS" mit Kennung "" in Klasse
"app.tools.GenSign" aufgerufen wurde.
Fehlerbeseitigung: Mit Hilfe des Benutzers, der für die Programmpflege
verantwortlich ist, die Fehlerursache bestimmen.
Technische Beschreibung . . . . . . . : Gibt die Ausnahme an, dass die
Java-Klasse nicht gefunden wurde, sicherstellen, dass sich die Klasse für
die Methode in dem Klassenpfad befindet. Gibt die Ausnahme an, dass die
Java-Methode nicht gefunden wurde, den Methodennamen und die Kennung
überprüfen. Ist die Kennung nicht korrekt, den RPG-Prototyp für die Methode
Hat mir jemand evt. einen Tip, was ich falsch mache ?

DANKE und Grüße :)

Stefan

mk
24-02-12, 09:32
Hallo,

mit diesem Aufbau wirst Du keine Freude haben.

Mein Tipp:

Erstelle für dein Java Programm einen Servicejob den man
z.B. über eine DTAQ aufrufen kann.
Den Job stellst Du mit RUNJVA in das System. Die Rückgabe
der Parameter kann man dann steuern wie man möchte.

Zu deinem Fehler:
Das System findet die Java Klasse nicht. Meistens liegt es
an den Parametern die die Java Klasse erwartet.

gruß
Michael

BenderD
24-02-12, 17:57
- Environment Variablen sind case sensitive (CLASSPATH nicht gleich Classpath)
- wenn die JVM bereits gestartet war, geht das sowieso in den Wind
- wenn die JVM vorher beendet wurde, geht das garnicht
- diese Programme mit embedded Java in RPG sind nicht wartbar
- darüber freut sich nur der Hardwarelieferant, pro Job, der das macht wird hier mehr CPU und Hauptspeicher verballert, als eine komplette Buchhaltung verbraucht

- schnell, stabil und skalierbar geht das mit AppServer4RPG (dann braucht man sich das asynchron Gedöns nicht selber schreiben.

D*B

dschroeder
27-02-12, 13:20
Hallo Stefan,
klappt der Aufruf bei dir jetzt? Wir hatten da auch erst einige Schwierigkeiten. Mittlerweile setzen wir den classpath per CL-Befehl "CHGENVVAR ENVVAR(CLASSPATH) ...". Zum Testen machen wir das auf Jobebene. Wenn alles läuft, machen wir das auf Systemebene. Eine echte Falle ist das, was die Kollegen auch schon geschrieben haben: Wenn die Java-VM einmal läuft, kann man den Classpath nicht mehr ändern. Es gibt scheinbar keine Möglichkeit, die Java-VM kontrolliert zu beenden. Da hilft dann nur abmelden und neu anmelden (bzw. Job beenden und neu starten). Dann den neuen classpath setzen und dann die erste Java-Funktion aufrufen. Die Java-VM liest den Classpath nur einmalig beim Start.

Gruß,
Dieter