Hallo Manfred,
erstmal Glückwunsch zur Ausschaltung des Störfeuers. ;D
Ich habe mich noch nicht mit LS2J beschäftigt. Wenn ich mit Java in Lotus arbeite ist es bislang immer pur-Java (etwa ein Agent, 1 Applet, 1 GUI, die von aussen zugreift).
Du hast da einen interessanten Punkt aufgebracht. Und das ist leider wieder so ein Ding, wo offenbar etwas nicht so sauber von Lotus implementiert bzw. dokumentiert wird.
Durch
return bufResult.toString()
wird ein Objekt erzeugt, dass den von der JavaVM verwalteten Heap Speicher belegt. Genau gesprochen ist es ein anonymes, lokales Objekt, da es von keiner Referenzvariable gehalten wird und Methoden-scope hat (keine Instanzvariable in ersten Version).
In einem reinen Java Programm würde das keine Probleme machen. Nach dem return der Methode wäre das Objekt eligible for garbage collection und der entsprechende Speicher würde zu einem geeigneten Zeitpunkt vom Garbage Collector freigegeben. Hmm genau gesprochen kann aus dem aufrufenden code das Objekt gehalten werden. Aber das ist in der Regel kein Problem... Arbeite später an umfangreicheren Erklärung...
Offenbar hält aber LS2J aus für mich derzeit nicht nachvollziebaren Gründen eine Referenz auf ein Objekt, das von einer Methode zurückgegeben wird, die einen nicht-void, nicht-primitiv-Datentyp (int, fload, boolean, etc.) besitzt. Solange eine Referenz auf das Objekt gehalten wird, ist es nicht "eligible for garbage collection".
Du hast den richtigen Weg gefunden. Du schreibst den String einfach in eine Instanz-Variable, die du pro Durchlauf überschreibst.
Beispiel:
1. Durchlauf:
after completion method void getRSSFeed():
Object-Instanz-Variable GetRssFeed.returnURLContent hält String-Objekt "foo".
2. Durchlauf:
after completion method void getRSSFeed():
Object-Instanz Variable GetRssFeGetRssFeed.returnURLContent verliert Referenz auf String-Objekt "foo" und hat neue Referenz auf neues String-Objekt "bar". Das String-Objekt "foo" ist eligible for Garbage Collection. "bar" wird referenziert.
usw.
Da der von der Java Virtual Maschine verwaltete Heap Speicher nicht mehr volläuft, schlägt der Java Garbage Collector in der neuen Version offenbar irgendwann zu.
Sierra/Bates Buch hat sicher ein Kapitel zu den Grundlagen von Java Garbage Collection ;D
Das hört sich alles komplizierter an als es ist.
Noch was: Bei Methoden mit void-Rückgabe benötigst du kein return. Das letzte return in der Methode kannst du entfernen.
Wie du weisst gibt es keine dummen Fragen, wenn du noch Fragen hast.
Ein anderer Weg wäre vielleicht mit einem Singleton zu arbeiten (später mehr).
Gruß Axel
Ein anderer Weg wäre vielleicht mit einem Singleton zu arbeiten (später mehr).
Hmm. LS2J behandelt das Objekt der Klasse GetRSSFeed offenbar als Singleton. Du erzeugst ja aus dem code immer neue Objekte der Klasse GetRSSFeed. Nur ist LS2J offenbar so schlau, dass es immer das selbe Objekt wiederverwendet. Sonst würde das mit dem Überschreiben der Instanzvariable returnURLContent so gar nicht funktionieren.
Dann wären nämlich mehrere Objekte vom Typ GetRSSFeed im Heap und es würden keine Instanz-Variablen überschrieben.
Singleton ist ein Design-Pattern, das benutzt wird, wenn man von einer Klasse genau 1 Objekt haben will.
Es wird so implementiert:
public class ASingleton {
// Klassenvariable. An Klasse nicht Objekt gebunden (static)
private static final Elvis INSTANCE = new Elvis();
// Konstruktor ist private. Kann nur aus Klasse selbst aufgerufen werden, nicht von aussen
private Elvis() {}
// das kann von aussen angesprochen werden. Gibt aber immer den selben Elvis zurück
public static Elvis getInstance() {
return INSTANCE;
}
}
wenn man in der Klasse mit Objekt-Serialisierung arbeitet, sind weitere Sachen zu beachten.
Übrigens kannst du deine Methode getRSSFeed() vielleicht auch als static-Methode implementieren und weiter mit String-Rückgabewert arbeiten.
Gruß Axel
Die ganze Geschichte ist ein bischen misteriös.
Es gibt eine reine Anwendungsentwickler-Sicht. Lotus stellt dieses LS2J zur Verfügung und der Entwickler kann nach bestimmten Regeln Java Objekte erzeugen, Methoden aufrufen etc.
In Wirklichkeit gibt es darunter eine systemische Schicht. Von dieser Komplexität soll der Anwendungsentwickler nix merken.
In Wirklichkeit sind das ja Kommunikationen zwischen zwei unterschiedlichen Prozessen. Die JVM läuft in einen anderen Prozess als Notes.
Wie wird jetzt die Connectivity zwischen den beiden Prozessen hergestellt?
Solange ich da keine Texte haben, die LS2J aus einer systemischer Sicht beschreiben, betreibe ich Kaffeesatzleserei.
Manchmal kommt man damit zu Ergebnissen, hier nicht.
Es soll aber nicht der Eindruck entstehen, dass dies Probleme sind, mit denen sich ein Entwickler von Java-Anwendungen normalerweise herumschlägt. Das macht gerade den Reiz aus.
Manfred, die sauberste Lösung wäre vermutlich überhaupt keine Objekte zu erstellen und alles über static abzufackeln (static Instanzvariblen, static Methoden).
Wobei deine Lösung natürlich völlig in Ordnung ist.
Beispiel:
public class AllStatic {
public static String aVar = "hier";
public static String getMsg() {
return "ist alles static";
}
public static void main (String args) {
System.out.println(AllStatic.aVar + " " + AllStatic.getMsg());
}
}
Es wird kein Objekt instanziiert. Da deine Klasse nur aus einer Methode besteht, könntest du dort genau so vorgehen.
Set getRSSFeedClass = js.GetClass("GetRSSFeed")
' nächstes nicht mehr nötig
'Set getRSSFeedObject = getRSSFeedClass.CreateObject ' 1x Object erstellen/instanzieren
...
' Properties wie URL, Proxy usw. setzen und zwar über getRSSFeedClass.Property="aProperty";
' Methoden-Header in Java: public static String getRSSFeed()
html=getRSSFeedClass.getRSSFeed();
ist total nicht Objekt-orientiert. Da der Java code aber eine genau definierte enge Aufgabe erfüllt, die in Zukunft nicht erweitert werden soll (wüsste nicht warum), ist dies vermutlich die pragmatischste Lösung.
Gruß Axel
Gruß Axel
Hatte ich ja geschrieben. Ich versuche, alle Tipps von Axel zu verstehen und probiere das mit Eclipse auch aus. In diesem konkreten Fall verstehe ich den Ansatz mit der "Static-Geschichte" noch nicht richtig, was da denn der genaue Unterschied ist.
Der Unterschied zwischen "normalen" Methoden
public String getRSSFeed(){}
und statischen Methoden
public static String getRSSFeed(){}
ist, dass du, um die "normale" Methode aufrufen zukönnen eine Instanz der Klasse benötigst
Set getRSSFeedClass = js.GetClass("GetRSSFeed")
Set getRSSFeedObject = getRSSFeedClass.CreateObject ' 1x Object erstellen/instanzieren
getRSSFeedObject.getRSSFeed()
statische Methoden kannst du ohne eine Instanz aufrufen
Set getRSSFeedClass = js.GetClass("GetRSSFeed")
getRSSFeedClass.getRSSFeed()