PDA

View Full Version : String Objekt aus RPG an Java übergeben ????



hoeppe
20-07-05, 10:09
Hallo,

ich weiß, die Fragen zum Aufruf von Java aus RPG nerven wahrscheinlich langsam und Dieter wird zurecht davon abraten, aber die Situation läßt mir keine Wahl.

Ich habe eine Beispielklasse erstellt mit einer Methode gibEcho, die einen String erwartet, etwas drankettet und diesen ans RPG zurückgibt. javap -s gibt folg. Signatur aus:

public class Iseriestest2 extends java.lang.Object {
public Iseriestest2();
/* ()V */
public java.lang.String gibEcho(java.lang.String);
/* (Ljava/lang/String;)Ljava/lang/String; */
}

Die Klasse sieht so aus:

public class Iseriestest2 {
public String gibEcho(String echostring){
echostring = "Echo from SVSMAINZ:" + echostring;
return echostring;}}

Das RPG so: (hier als Link (http://hoeppe.de.vu/files/bestabfrag.txt), dann ist die Formatierung noch da)

HTHREAD(*SERIALIZE) DftActGrp(*NO) ActGrp(*CALLER)
F
D str S O CLASS(*JAVA:'java.lang.String')
D fld S 10A VARYING
D
D makestring PR O EXTPROC(*JAVA:'java.lang.String':
D *CONSTRUCTOR)
D CLASS(*JAVA:'java.lang.String')
D parm 10A VARYING
D
D getbytes PR 10A EXTPROC(*JAVA:'java.lang.String':
D 'getBytes') VARYING
D
D gibEcho PR O EXTPROC(*JAVA:'Iseriestest2':
D 'gibEcho')
D CLASS(*JAVA:'java.lang.String')
C
C eval fld = 'ABCDEFGHIJ'
C eval str = makestring(fld)
C eval str = gibEcho(str)
C eval fld = getBytes(str)
C dsply fld
C eval *inlr = *on
C

Wenn ich richtig liege, ist der Prototyp für gibEcho hier auch mit einem Ein- und Ausgangsparameter jeweils vom Typ String definiert. Ich bekomme aber den Fehler RNQ0301
Ursache . . . . : RPG-Prozedur BESTABFRAG in Programm VDBTAO/BESTABFRAG hat
Java-Ausnahme "java.lang.NoSuchMethodError: gibEcho" empfangen, als die
Methode "gibEcho" mit Kennung "()Ljava.lang.String;" in Klasse
"Iseriestest2" aufgerufen wurde.

Laut Kennung meint die VM? hier, dass kein Eingabestring erwartet wird, oder ?? Wenn ich beim Prototyp von gibEcho aber zusätzlich ein String Objekt als Übergabewert definiere, wirds gar nicht erst kompiliert.

Bitte um Hilfe!

mk
21-07-05, 08:23
Hallo,

die Meldung sagt das die Methode nicht gefunden wurde.

Ist denn die Classpath variable auch richtig gestezt ?
ADDENVVAR ENVVAR(CLASSPATH) VALUE

Vielleicht ist es hilfreich wenn Du erstmal eine Methode
ohne Rückgabewert aufrufst. Dann weiß man erstmal das es
grundsätzlich klappt.

gruss
Michael

hoeppe
21-07-05, 08:57
Hallo mk,

danke für die Antwort, aber der Classpath sollte richtig sein. Wenn ich ihn weglasse bekomme ich einen NoSuchClassError oder so ähnlich. Ich denke also beim NoSuchMethodError wird die Klasse schon gefunden. Der Hilfetext zum Fehler lässt sich ja auch mehr über den möglicherweise falschen Methodennamen und die Übereinstimmung der Parameter und Rückgabewerte von Prototyp und Klasse aus. Ich denke immer noch bei Letzterem liegt der Fehler, oder??

Passen denn nach Deiner Meinung Methode, Prototyp und Aufruf zusammen?

public String gibEcho(String echostring){
echostring = "Echo from SVSMAINZ:" + echostring;
return echostring;}
--------------------------------
D gibEcho PR O EXTPROC(*JAVA:'Iseriestest2':
D 'gibEcho')
D CLASS(*JAVA:'java.lang.String')
--------------------------------
eval str = gibEcho(str)

Werde aber erstmal Deinen Tipp nachvollziehen.
Nochmals Danke

hoeppe

mk
21-07-05, 11:03
Hallo ,

ich hänge Dir ein Muster an.

Damit funktioniert der Aufruf.

Gruss
Michael

hoeppe
21-07-05, 12:27
Hallo Michael,

danke für die Mühe, aber so ein Beispiel hatte ich schon zum Fliegen bekommen. Bei meinem Problem geht es ja um die Problematik der Übergabe von Objekten als Parameter.

Ich habe mein Problem gelöst, indem ich dem Prototyp der gibEcho Methode noch einen Übergabeparameter verpasst habe (obwohl ich der Meinung bin, dass das gestern noch vom Compiler abgelehnt wurde)

public String gibEcho(String echostring){
echostring = "Echo from SVSMAINZ:" + echostring;
return echostring;}
--------------------------------
D gibEcho PR O EXTPROC(*JAVA:'Iseriestest2':
D 'gibEcho')
D CLASS(*JAVA:'java.lang.String')
D parm O CLASS(*JAVA:'java.lang.String')
--------------------------------
eval str = gibEcho(str)

Übrigens kleiner Tipp der von allg. Interesse sein könnte:
Die Kennung "()Ljava.lang.String;" im Fehlertext eines RNQ0301 java.lang.NoSuchMethodError gibt nach meiner Ansicht Auskunft darüber, mit welchen Parametern die Methode aktuell gerufen wurde (hier fehlt also der Eingabwert, weil leere Klammer) und sagt nicht aus, wie die Parameter denn sein sollten!

Gruß
Hoeppe

B.Hauser
21-07-05, 12:34
Bist Du sicher, dass der Constructor für Dein String Objekt auf die richtige Klasse zeigt bzw. dass im Prototyp das richtige Objekt angegeben wurde?

Du verwendest "java.lang.String" in der Fehlermeldung steht
"Ljava.lang.String".

hoeppe
21-07-05, 14:04
ja, bin ziemlich sicher.
Das 'L' in "Ljava.lang.String" bedeutet lediglich, dass es sich bei dem Parameter um ein Objekt bzw. eine Objektreferenz handelt. Siehe hier (http://www.rgagnon.com/javadetails/java-0286.html).

Wie ich oben schon schrieb, funktioniert es jetzt endlich :-)

Wer Interesse an einem brauchbaren Mini-Beispiel für die Über- und Rückgabe eines String Objektes von RPG nach Java hat, findet als Anhang beide Quellen (oder hier (http://hoeppe.de.vu/files/RPG2Java%20Uebergabe%20String%20Objekt.txt)).

Sehr wichtig ist die Groß/Kleinschreibung beim CLASSPATH zu beachten und den letzen Backslash wegzulassen (z.B. '/home/VDBPGMR' )

Gruß
Hoeppe

BenderD
22-07-05, 08:03
Hallo,

ich erspare mir alle Kommentare warum man sowas nicht macht, das kann man im Detail auf meiner Webseite nachlesen und dieses Beispiel spricht für (oder besser gegen) sich.



Übrigens kleiner Tipp der von allg. Interesse sein könnte:
Die Kennung "()Ljava.lang.String;" im Fehlertext eines RNQ0301 java.lang.NoSuchMethodError gibt nach meiner Ansicht Auskunft darüber, mit welchen Parametern die Methode aktuell gerufen wurde (hier fehlt also der Eingabwert, weil leere Klammer) und sagt nicht aus, wie die Parameter denn sein sollten!

Gruß
Hoeppe

Zu obiger Bemerkung:
Java arbeitet (wie SQL und C ebenso) mit Overloading, sprich: man kann in der gleichen Klasse Methoden mit gleichen Namen haben, wenn sie sich in der Parameterschnittstelle unterscheiden und es wird dann immer die passende aufgerufen.
class TestUnfug
{
String getEcho()
{
return "Quatsch";
}
String getEcho(String huddel)
{
return huddel;
}
}
Das sind zwei verschiedene Methoden!!! und wenn ich jetzt versuchen würde:
new TestUnfug().getEcho("Hugo", "Otto");
dann bekäme ich wieder eine noSuchMethod , weil es eben keine Methode String getEcho(String a, String b) in TestUnfug gibt.

Es sei hier nur am Rande erwähnt, dass einen der Java Compiler von vornherein von diesem Quatsch abgehalten hätte, der prüft nämlich ob passende Signaturen da sind.

mfg

Dieter Bender

hoeppe
22-07-05, 08:57
Hallo Dieter,

danke für die klärenden Worte. Ich wollte mit meinem Tipp auch nur feststellen, dass mir die Fehlermeldung leider nicht sagt, welche Parameter die gerufene Methode denn verlangt, sondern mit welchen sie aktuell gerufen wurde.
Dadurch habe ich erkannt, dass ich einen Parameter zuwenig übergeben habe. Anfangs hatte ich halt immer vermutet, die Fehlermeldung sagt mir was ich mitgeben soll und dieses Herumrätseln wollte ich Anderen ersparen.

Gruß
Hoeppe

BenderD
22-07-05, 09:46
Hallo,

warum soll eine Fehlermeldung "nichtGefunden" sagen was sie gefunden hätte, wenn man denn was anderes hätte aufrufen wollen???
Gleicher Name unterschiedliche Schnittstellen ist für Java was völlig verschiedenes!
Was das rumrätseln angeht: vielleicht ist es doch besser erst die Java Grundlagen zu lernen und dann zu versuchen Dinge auszuprobieren, die eh' nicht vernünftig funktionieren.
Alle Versuche mit Java RPG Mix eine Anwendung zusammen zu dengeln sind gescheitert - und immerhin waren ja fast 10 Jahre Zeit.
mfg

Dieter Bender


Hallo Dieter,

danke für die klärenden Worte. Ich wollte mit meinem Tipp auch nur feststellen, dass mir die Fehlermeldung leider nicht sagt, welche Parameter die gerufene Methode denn verlangt, sondern mit welchen sie aktuell gerufen wurde.
Dadurch habe ich erkannt, dass ich einen Parameter zuwenig übergeben habe. Anfangs hatte ich halt immer vermutet, die Fehlermeldung sagt mir was ich mitgeben soll und dieses Herumrätseln wollte ich Anderen ersparen.

Gruß
Hoeppe