Das Notes Forum

Lotus Notes / Domino Sonstiges => Java und .NET mit Notes/Domino => Thema gestartet von: Mark³ am 06.04.06 - 15:13:35



Titel: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 06.04.06 - 15:13:35
Ich nutze Java-Agenten in Notes, um auf HP Openview Service Desk mit der web-api zuzugreifen. Für diejenigen, die Openview nicht kennen: Mittels der web-api erzeuge ich ein Objekt vom Typ ApiSDSession, mit welchem ich alle Aktionen im Openview Service Desk ausführen kann. Der Server dazu steht irgendwo im WAN.

Der Fehler 'error cleaning up agent threads' entsteht dadurch, dass ein Notesagent andere Threads startet und beim Beenden nicht weiß, ob die anderen Threads alle ebenfalls beendet wurden. Das Objekt ApiSDSession hat die Methode closeConnection(), womit die Verbindung zum Openview-Server beendet wird. Nun kann man das Objekt auf null setzen und alles ist im Lot. Nur merkt Notes das leider nicht.
Bei Notes.net gibt es eine Technote, um den Fehler einzugrenzen. Dafür sammelt man alle Threads aus der Threadgroup, in der der aktuelle Agent läuft. Normal findet man zwei Threads, die beide zum Notesagenten gehören. Bei mir finde ich 4 Threads, zwei haben den Namen 'WeakReference Plumber' die wohl zu dem Openview-Objekt gehören.
Zu WeakReference habe ich in einer Javadokumentation gefunden, dass solche Objekte ruhig garbage collected werden können auch wenn  man nicht sicher ist ob sie ordentlich finalisiert wurden (ich bin hier nicht so der Experte auf diesem Gebiet). Scheinbar hilft Notes das nicht.
Wenn ich diesen Agenten nun mehrmals hintereinander aufrufe bekomme ich einen Speicherüberlauf in der JVM (die DB liegt auf dem Server, den Agenten starte ich über einen Button in einem Dokument). Dies scheint aber nur bei unseren 6.03-Installationen aufzutreten. Beim 6.54 bekomme ich zwar auch den '...cleaning up...'-Fehler in der Konsole, aber keinen Speicherüberlauf.  :'(

Habt ihr noch Ideen, wie ich das umschiffen könnte? Die web-api.jar (und auch die anderen Java-Klassen) nutze ich übrigens, indem ich alle Klassen in Eclipse entwickle und als Notes Agent mit Imported Java ausführe (keine Einträge in der Notes.ini oder so)

Jede Anregung willkommen... O0


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 06.04.06 - 17:44:18
keine konkrete Lösung.
Der Begriff WeakReferences wird meistens für konstrukte wie folgt gewählt ->
Ein Objekt ist eligible for garbage collection, wenn keine Referenzen aus anderen Objekten auf dieses Objekt mehr existieren.
Manchmal ist es wünschenswert, dass Objekte auch dann eligible for garbage Collection sind, wenn sie noch in bestimmten Container-Objekten wie Maps referenziert werden (z.B. ist WeakHashMap eine konkrete Implementierung davon). Das Objekt muß dann selbst in eine WeakReference gewrappert werden. 
Verdammt viele googles gegen solche weiterführende Java-Geschichten landen übrigens immer in der gleichen Quelle:
http://javaalmanac.com/egs/java.util/coll_WeakMap.html

Idee: Vielleicht kannst du selbst die Objekte auf Null setzen, die von WeakReferencePlumber referenziert werden? Oder dir zumindest per Debugger oder ähnlichem einen Überblick zu verschaffen.

Deine Idee mit Imported Java könnte eventuell zu den OutOfMemoryException führen.
Kannst du die in Eclipse entwickelten Klassen nicht einfach in ein jar packen und dann in lib/ext der VM? Wenn das zu Deployment Problemen führt, weil das lokale Agenten sind, kann man das evtl. über Mails verteilen. Wir hatten solche OutOfMemories wenn ich mich recht erinnere auch z.B. wenn JDBC Treiber an den Agent gehängt wurden statt sie in UserClasses oder in java/lib/ext zu tun.

Gruß Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 07.04.06 - 07:30:26
Hallo Mark!

Zusätzlich zu dem was Axel schon so gut erklärt hat. Sehr häufig werden Weakreferences für Cache Kostrukte hergenommen und sollten eigentlich verhindern, dass der Cache den Speicher sprengt. Aber etwas anderes, ich mache eigentlich kaum noch diese Java Agent Sachen, da es mir einfach zu wenig stabil ist (Lotus sollte da wirklich mal was tun). Ausserdem ist halt JDK 1.3.1 mittlerweile schon ein wenig fad. Ich habe beste Erfahrung gemacht, dass ausserhalb des Domino Servers in einer eigenen JVM zu betreiben. Das läuft mit wesentlich besserer Performance da bessere JVM und man hat wesentlich weniger Probleme mit den ganzen Besonderheiten von Notes. Also einfach mal den Agent in ein externes Programm auslagern und das ganze kann ja dann auch über ein Programmdokument bequem zeitgesteuert vom Server aufgerufen werden.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 08.04.06 - 09:56:37
Mark,

beide von dir geschilderten Probleme sind im Prinzip Plattform-Probleme. Genauer Plattform-Probleme der Java Runtime in Notes.
Das Problem ist, dass die Designer der Plattform Java in Notes diese Probleme nicht vorhergesehen haben. Genau das ist die Wurzel aller "Java isn't very well implemented in Lotus Notes"-Diskussionen.

Plattform-Probleme treten überall auf.
Z.B. sollte man mal versuchen einen Ankerlink innerhalb von Jsr-168 Portlets zu programmieren. Es ist deutlich schwerer als man denkt und am Ende habe ich es ohne Ankerlink programmiert.

Der Grund?
Zitat
All the decisions, all the architecture, all the languages, the tools, the databases, the protocols, the hardware, they are all the way they are because we zigged instead zagged.
http://damienkatz.net/2006/03/my_new_favorite_1.html

Bei Plattformproblemen entstehen sehr oft unabsehbare Kosten. In Notes-Java gibt es  eine Menge dieser Issues. Vermutlich dauert deshalb die Eclipsierung von Notes so lange. In Java Plattformen (J2EE-basiert, Kombinationen von OS-Frameworks, Eclipse, etc) gibt es diese spezifische Häufung von Problemen nicht. Probleme - d.h. Aufgabenstellungen, die sich als deutlich komplexer herausstellen als man erst denkt, gibts natürlich überall.

Was ich eigentlich sagen will: Um das WARUM dieser 2 gemeldeten issues zu ermitteln, muß man vermutlich wirklich tief buddeln.  ;D

Gruß Axel

Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 07:46:05
Vielen Dank für die Hinweise, scheinbar ist Notes so nicht in der Lage mit imported java umzugehen.
Einige Anwender bekommen auch die Fehlermeldung:
Code:
JVM: Attempt to retrieve Java agent attachments failed

Die jar für Openview ist 3.7MB groß, das ist bestimmt nicht gut, die im Agenten zu importieren.
Ich denke, ich muss die Openview-Logik auf dem Server zentralisieren und die Aktionen der Anwender dann asynchron verarbeiten. Wo sollte die große jar-Datei dann liegen, auf dem Server mit JavaUserClasses in der Notes.ini (bzw. Configuration-Dokument) oder geht es auch als Skriptlibrary in der Datenbank?
@Ralf: Wenn ich eine eigene VM für das Programm nehmen würde, wie würde ich das dann einbinden? Per Programmdokument kann ich das ja nicht ereignisgesteuert laufen lassen, oder? TriggerHappy von Damien Katz könnte ich als Trigger nehmen aber das erscheint mir irgendwie zu krumm...

Vielleicht habt ihr noch ein paar Ideen, wenn ich die Anforderung konkretisiere: Ich verwalte in der Notesdatenbank Empfangsbestätigungen für Hardware, die dann digital signiert werden. Der jeweilige Zustand der Bestätigung muss dann mit Openview synchronisiert werden.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 10.04.06 - 07:53:14
Die Ereignissteuerung ist ebenso kein Problem, du reduzierst deinen Agenten mit den richtigen Triggern einfach auf einen shell Command in dem du die externe JVM mit deinem Java Code aufrufst. Sollte normalerweise kein Problem sein.

Jetzt mal zu deiner konkreten Anforderung. Leider schreibst du nicht, wieviele Transaktionen so bei deinem System laufen. Falls es viele sind, würde es sich eventuell lohnen, dass dein Java Programm permanent läuft. Und du könntest es ja dann so programmieren, dass es auf einen Socket horcht und von dort die Notes ID der zu verarbeitenden Dokumente annimmt. Dann sparst du den großen Overhead des Starts der JVM und ausserdem würde dein Programm vom JIT Compiler besser compiliert. Eventuell könnte man es auch mittels Webservices realisieren.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 10.04.06 - 08:03:30
dass dein Java Programm permanent läuft.
... und genau hier könntest du über Java RMI nachdenken, weil es vermutlich einfacher ist (ist es wirklich).
Oder vielleicht auch Webservices.
Bzgl. Socket
Die de.comp.lang.java Legende Stefan Matthias Aust hat hier ein kurzes 3-teiliges Beispiel wie man -sagen wir - etwas in Java programmiert, dass auf ein Socket horcht. Ein Webserver. Ist sehr ähnlich.
http://groups.google.de/groups/search?hl=de&q=Do+it+yourself+webserver&qt_s=Suche


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 08:12:39
Ich habe so etwa 100 Transaktionen pro Tag.
Ich hatte ja bereits mal einen RunJava-Task auf meinem Server laufen, das lief eigentlich sehr gut. Vielleicht sollte ich den Laufen lassen und dort alle Verbindungen von allen meinen Datenbanken zu Openview bündeln. Allerdings ist das irgendwie nicht so wartungsfreundlich und auch nicht modular.
Ich werde mal die verschiedenen Modelle durchdenken. Übrigens läuft der Server auf 6.54, bald aber auf 7.01, da ist die VM vielleicht ja wieder etwas schneller!?


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 10.04.06 - 08:22:38
Java als Plattform besitzt genug Remoting-Mechanismen, mit denen man das
a) stabiler
b) skallierbarer
c) wartbarer
d) auditierbarer
e) sicherer
f) transparenter
g) übersichtlicher

durchführen kann.
RMI, Server-Prozess oder Webservices. Es ist nicht so schwierig.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 10.04.06 - 08:24:09
Meiner Meinung nach, würde es sich bei 100 Transaktionen sicher schon lohnen, den Task den ganzen Tag laufen zu lassen. Ich finde gerade die externe Programmierung viel wartungsfreundlicher, da ich dann den Java Code in einer vernünftigen Entwicklungsumgebung habe und nicht immer in den Designer einkopieren muß.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 09:09:33
ok, ich versuche mal, das bisher Gesagte zusammenzufassen:

  • Die Transaktionen mit Openview werden in einer einzigen Java-Anwendung gebündelt, die außerhalb der Domino JVM läuft
  • a) Die Transaktionen werden entweder per Shell-Befehl gestartet (Nachteil: viel Overhead durch häufige Starts der Anwendung) oder b) die Anwendung selbst überwacht aktiv eine/mehrere Domino-Datenbanken oder c) die Anwendung läuft ständig und wird über RMI oder SOAP angesprochen
  • Der Vorteil bei c) wäre natürlich, dass ich synchron eine Antwort erhalten könnte. Ich würde also per Notes-Java-Agent remote auf meine Openview-Mittelschicht zugreifen und könnte die Ergebnisse direkt in mein DocumentContext einfließen lassen.

Die Lösung c) würde ich anpeilen, ich weiß allerdings nicht, ob ich dann wieder mit 'Error cleaning up agent threads' zu kämpfen habe.
Und ein eigenständiges Java-Programm, welches andauernd läuft, wie sähe das aus? Nimmt man da einen Service (Windows!) ? Oder kann ich es so wie im Webserver-Beispiel realisieren? Da fehlt mir leider die Übersicht...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 09:15:04
noch ein Nachtrag für Openview-Nutzer: Die Web-Api dient eigentlich dazu, Openview per JSP anzusprechen, daher läuft bei den meisten Installationen auch bereits ein Web Application Server auf dem Openview-Server mit. Leider kann ich diesen aber aus organisatorischen Gründen nicht nutzen und dort direkt Webservices programmieren...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 10.04.06 - 09:17:15
Ich weiß jetzt nicht, was du für ein Websever Beispiel du meinst. Aber prinzipiell würde Lösung c so wie du es beschrieben hast funktionieren.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 09:22:19
das Beispiel aus Antwort #6 von Axel meinte ich...
Mir fällt noch ein, dass ich schon mal testweise einen Tomcat aufgesetzt hatte um JSP zu nutzen. Die Programmierung war mir da zu umständlich, aber vielleicht kann ich auf dem Tomcat ein paar Webservices implementieren...Allerdings wäre mir die eigenständige Java-Anwendung lieber, da ich dann nicht noch zusätzlich den Tomcat warten müsste.
Das Problem an der ganzen Sache ist wie so oft, dass sie keine Zeit kosten darf (und damit auch kein Geld). Ist natürlich nicht ganz zu erreichen, aber die Lösung mit dem wenigsten Aufwand gewinnt, nicht die mit der besten Umsetzung...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 10.04.06 - 09:53:10
rmi könnte das einfachste sein. Ich kann mich heute abend mal mit Domino 7 dran probieren.
Länger nicht mehr gemacht, aber afaik geht das auch über http getunnelt (falls offene Ports ein Problem darstellen).
In der Java Develloper (nicht Programmer) Zertifizierung (die ich nicht habe) wird das Programmieren eines Remoting-Beispiels gefordert. Da kann man zwischen Socket und RMI auswählen. Machbar ist das auf jeden Fall. Imho auch in einem wirklich vertretbaren zeitraumen.
Wenn die Anwendung verteilt über das Netzwerk geht, gibts natürlich eine Menge möglicher Fehlerquellen für einen reibungslosen Betrieb. Das ist aber gut dokumentiert.
Ich denke, ich fang heute abend mal mit einem rmi Beispiel für Domino 7 (hab zu Hause zur Zeit nix anderes, ist btw. relativ egal) an. Sollte ich eigentlich noch können.

Gruß Axel   


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 13:03:41
Zwischenstand:
Als Workaround (ITIL lebe hoch) habe ich erstmal die großen jars (Web-api für Openview und Openlog-Funktionen) in eine Java-Lib in der Datenbank gepackt und die Agenten von Imported Java auf Java umgestellt.
Nachteil: Ich entwickle weiterhin in Eclipse, muss den Sourcecode aber in den Notesagenten reinpasten anstatt nur Refresh zu drücken
Vorteil: Bei einem ersten Test schint der Fehler nicjht mehr aufzutreten. Habe in der Debug-Konsole mal mit m einen Memorydump gemacht nach jeweils einer Transaktion. Ergebnis:

1. 84% free
2. 34% free
3. 34% free aber 70k weniger als bei letztem Schritt
4. 34% free aber 70k weniger als bei letztem Schritt
5. 34% free aber 70k weniger als bei letztem Schritt
6. 80% free

Anscheinend läuft der Garbage Collector und erlöst den Client dann vom Speichermüll. Leider bekomme ich aber immer noch 'Error cleaning up agent...' daher möchte ich langfristig auf jeden Fall die Openview-Zugriffe separat in einer vernünftigen VM laufen lassen.
Im Agenten rufe ich zwar auch ein System.gc() am Ende auf, aber das scheint nicht direkt was zu tun sondern eher ein Tip für die VM zu sein, die Garbage Collection eher früher als geplant laufen zu lassen.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 13:11:44
hier noch mal ein paar Details zu meinem Recycling, vielleicht ist hier ja auch ein Wurm drin:

Code:
public void NotesMain() {
oli = new OpenLogItem();
try {
session = getSession();
AgentContext agentContext = session.getAgentContext();
DocumentCollection dc = agentContext.getUnprocessedDocuments();
Agent agent = agentContext.getCurrentAgent();
db = agentContext.getCurrentDatabase();
profileDoc = db.getProfileDocument("abc", "");

ov = new OVTool();
if (ov != null) {
...
Document doc = dc.getFirstDocument();
while (doc != null) {

doc = dc.getNextDocument();
}
ov.disconnect();
ov = null;
}

profileDoc.recycle();
db.recycle();
agent.recycle();
agentContext.recycle();
session.recycle();
}

catch (Exception e) {
oli.logError(e);
System.gc();
}
oli.recycle();
System.gc();
}

Und noch ov.disconnect() im Detail:

Code:
public void disconnect()  {
oli.recycle();
s.closeConnection();  //beendet die Openview Session
s = null;

}

In meiner Iteration der DocumentCollection könnte ich noch ein tempDoc deklarieren und damit bei jedem Durchlauf das momentane doc recyclen (habe ich bei notes.net als aggressives oder so ähnlich Recycling gesehen aber der Sinn hat sich mir nicht erschlossen da das Recyclen der DocumentCollection doch eigentlich auch alle docs mitnehmen sollte, die dadrin sind, oder? Gleiches müsste dann natürlich auch für die db und die session gelten. Ist also alles nicht 100%ig verstanden von mir...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 10.04.06 - 13:26:23
Das recycle läuft falsch.

Grundregel: Nur Dokumente recyceln, die du selber erstellt hast. Also auf keinen Fall die Session und den AgentContext recyceln.

Für was du das Objekt agent brauchst entzieht sich ebenfalls meiner Kenntnis. Komisch ist auch die Zeile oli.recycle(). Ist da auch ein Notes Objekt?

Übrigens das mit dem Cleaning up agent Threads ist ja eigentlich keine Fehlermeldung im eigentlichen Sinn, sondern nur ein Hinweis, dass Threads gekillt wurden, die dein Code nicht ordnungsgemäß abschgeschlossen hat. Eventuell solltest du mal deinen OpenView Code in einem Debugger laufen lassen und schauen welche Threads da überbleiben und ob die eine Möglichkeit bieten das zu beenden. System.gc muß nicht aufgerufen werden, vor allem nicht in einem Server.

Zum recyceln in der Schleife, das sollte man auf jeden Fall machen. Wenn die Schleife nur ein paar mal durchlaufen wird, hast du sicher noch kein Problem. Wenn die Schleife jedoch 1000te mal durchlaufen wird, dann bekommst du garantiert ein Memory Problem. Also in Schleifen das Doc immer nach Verwendung recyclen.

Die Document Objekte werden erst beim GetNextDocument erstellt. Was aber stimmt, ist das alle Dokumente die noch nicht recycelt waren beim Recyceln der DC mitgenommen werden. Aber bis dahin kann schon OutOfMemory aufgetreten sein.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 13:44:59
es ist immer schön, mal wieder was dazuzulernen  :)
Die Recycling-Geschichte werde ich nochmal aufgreifen.
Zu oli: das ist das OpenLogItem (OpenLog von openntf.org), für mich gehört das schon selbstverständlicherweise in jede Datenbank rein. (Ich hatte es zum Testen mal komplett rausgelassen, hatte aber keinen Einfluss auf den cleaning up-Mist).
Das agent-Objekt nutze ich, um den Namen des Agents ins Log zu schreiben, ist natürlich Blödsinn, weil das Log sowieso den Namen automatisch logged...

Was sagst du dazu?

Code:
public void NotesMain() {
oli = new OpenLogItem();
try {
session = getSession();
AgentContext agentContext = session.getAgentContext();
DocumentCollection dc = agentContext.getUnprocessedDocuments();
db = agentContext.getCurrentDatabase();
profileDoc = db.getProfileDocument("setup", "");
ov = new OVTool();
if (ov != null) {
Document doc = dc.getFirstDocument();
Document temp = null;
while (doc != null) {
...
temp = dc.getNextDocument(doc); // get the next one
doc.recycle(); // recycle the one we're done with
doc = temp;

}
ov.disconnect();
ov = null;
}
profileDoc.recycle();
db = null;
agentContext = null;
session = null;
}

catch (Exception e) {
e.printStackTrace();
oli.logError(e);

}
oli.recycle();

}


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 10.04.06 - 14:19:02
das geänderte Recycling erlöst mich leider nicht vom cleaning up-Krams. Das liegt wohl wirklich daran, dass Notes die Openview-Geschichte nicht richtig entsorgen kann.
Leider tritt auch der Speicherüberlauf immer noch auf. Bei mir läuft das alles aber bei einem Kollegen trat er wieder auf, obwohl ich nun die jars in eine lib gepackt habe (und vor erneutem Testen die cache.ndk gelöscht habe).

Also doch eigenständiges Java-Programm mit RMI oder sowas. Leider weiß ich noch nicht so richtig, wo ich damit starten soll. Mal sehen, ob Axel was mit Notes 7 und RMI rausfindet, ansonsten werde ich wohl erstmal etwas Literaturrecherche betreiben müssen.
Im Prinzip brauche ich ja nur ein Javaprogramm, welches im main() in einer Endlosschleife auf irgendwelche Ports oder Sockets hört und dann für jeden Aufruf einen Thread laufen läßt, welcher eine Openview-Transaktion durchführt und ein paar Daten zurückmeldet, die ich wieder über Socket an den Caller zurückgebe.   O0


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 10.04.06 - 15:00:45
Das einzige Risiko bei rmi sehe ich in firewall Problemen (rmi port nicht offen).
Man kann das heute aber über http oder sogar ssh tunneln (http://www.pankaj-k.net/archives/2003/11/rmi_over_ssh.html).

Ansonsten ist rmi an vielen Stellen gut dokumentiert. Zb. im Handbuch der Javaprogrammierung (www.javabuch.de). Mit der Vor-Vor-Vorgängerversion hab ich das mal vor 5 Jahren aus Domino heraus gemacht. Der Aufbau ist erst einmal ein bischen fricklig. Geht aber.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 10.04.06 - 19:01:26
Ansonsten wird das in Kapitel 46 der Version 3 von Javabuch.de ausführlich beschrieben.
Im Kapitel davor (45) wird Socket-Programmierung beschrieben.
Das sind die beiden Alternativen.
Falls du irgendwo hängen bleibst, kannst du ja posten.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 11.04.06 - 09:07:01
ich versuche das mal mit Socket-Programmierung.

Ausgehend vom Webserver-Example aus Javabuch (4. Auflage, Kap. 45.3.3) erstelle ich eine simple Server-Anwendung
Code:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
/**
* @param port
*            the port which the server is listening to
*/
public static void main(String[] args) {
{
if (args.length != 1) {
System.err.println("Usage: java Server <port>");
System.exit(1);
}
try {
int port = Integer.parseInt(args[0]);
System.out.println("Listening to port " + port);
int calls = 0;
ServerSocket httpd = new ServerSocket(port);
while (true) {
Socket socket = httpd.accept();
(new ClientThread(++calls, socket)).start();
}
} catch (IOException e) {
System.err.println(e.toString());
System.exit(1);
}
}
}
}

die auf eingehende ClientThreads wartet:

Code:
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.Socket;

public class ClientThread extends Thread {
private Socket socket;

private int id;

private PrintStream out;

private InputStream in;

public ClientThread(int id, Socket socket) {
this.id = id;
this.socket = socket;

}

public void run() {
try {
System.out.println(id + ": Incoming call...");
out = new PrintStream(socket.getOutputStream());
in = socket.getInputStream();
readRequest();
createResponse();
socket.close();
System.out.println(id + ": Closed.");
} catch (IOException e) {
System.out.println(id + ": " + e.toString());
System.out.println(id + ": Aborted.");
}
}

private void createResponse() {
}

private void readRequest() throws IOException {
}

}

Nun würde ich in readRequest() Befehle parsen, mit denen ich Transaktionen in Openview ausführe. Die Ergebnisse der Transaktionen gebe ich dann per createResponse() wieder an den Caller zurück. Der Caller wäre in diesem Fall ein Notes Java-Agent.

Irgendwelche Vorschläge, wie man am besten Befehle parsed oder Objekte zwischen readRequest() und createResponse() austauscht?
Im Webserverbeispiel wird natürlich Text ausgelesen da ja normalerweise URLs geparsed werden. Ich könnte Klartextbefehle ('Create Servicecall', 'Axel Janssen', 'Netzwerkprobleme, kein Anschluß ans Netz') nehmen, aber ich möchte möglichst wenig selber parsen. Leider habe ich da kaum Erfahrungen, was in Java so gebräuchlich ist. Mit StringTokenizer oder Vector() oder so kann man das ja recht flexibel machen.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 11.04.06 - 09:20:44
Hätte RMI genommen, aber ich schau heute abend mal nach.
Das Problem besteht darin, dass du quasi irgendwann anfängst ein eigenes Protokoll zu designen, wenn die Anforderungen zu komplex werden. Das sollte auf jeden Fall vermieden werden.
Was spricht einfach dagegen einfach einen Tomcat als Server für die OpenView Geschichten zu nehmen?
- Von Notes kann das per jakarta.commons.HttpClient gut angesprochen werden. OpenView-Methodennamen, HttpParameter sind HttpPost-Felder.
- Servlet-Programmierung kannst du. Die Business Logik der OpenView Geschichten wird vom Servlet aufgerufen.
- Du generierst einfach xml als Response.

Gruß Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 11.04.06 - 09:42:34
wahrscheinlich ist Tomcat die einfachste Lösung, sonst komme ich vom Hundertsten ins Tausendste...

Ich habe bloß noch ein Problem, mir das gesamte Bild vorzustellen, da ich bei Webanwendungen immer die Webseiten vor Augen habe, die ich im Client öffne. Dann könnte ich doch eigentlich den ganzen Kram sogar über AJAX ansprechen ???
Allerdings ist das mit http und unseren Firewalls so eine Sache hier.
Angenommen ich habe einen Tomcat, dann erstelle ich ein J2EE-Projekt und stecke die Logik nicht in JSPs sondern nur in Servlets, die ich dann per Lotusscript- oder Javaagent anspreche?


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 11.04.06 - 09:52:26
Ich glaube jetzt kommst du in ein falsches Fahrwasser. Man sollte nicht mit Kanonen auf Spatzen schiessen.

Ich würde es ganz einfach und effektiv lösen wie z.B. auf dieser Seite beschrieben.

http://java.sun.com/docs/books/tutorial/networking/sockets/clientServer.html

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 11.04.06 - 09:59:48
das ist immer das Blöde, wenn man keine Übersicht hat. Sicher kriege ich alles irgendwie hin. Welche der zig Lösungen aber am schnellsten zum Ziel führt kann ich überhaupt nicht abschätzen... :'(


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 11.04.06 - 10:11:31
Marc,

wieso Ajax? Du musst einfach mit jakarta.commons.HttpClient einen HttpRequest zusammenbauen, abschicken und synchron auf die Antwort warten.
Diese Antwort dann parsen.
Mach einfahc die Augen zu und bitte deinen Nachbarn ein paar Webseiten aufzurufen. Stelle dir dann die einlaufenden Antworten im Browser als Streams von Bytes vor  ;D


Ralf,

Die Frage ist was hier die Kanonen sind. Ist es bei diesem Argument eigentlich immer.

ist nicht in Wirklichkeit die Implementierung dieses (Originalzitat) KnockKnock Protokoll schwieriger ist als Tomcat einzusetzen?
Denke an Errorhandling. Information der Administratoren. Und und und. 

Vor allem wenn die in der Organisation schon Erfahrungen mit Tomcat haben.
Für die Administratoren ist es einfacher.
Für die Maintainer ist es einfacher.
Erweiterungen sind einfacher.
Vielleicht kann man später Dinge nutzen, die schon in Tomcat implementiert sind.

Eingebettete Tomcats werden btw völlig ernsthaft als Komponente für Standalone Anwendungen verwendet. Zb. bei der Hilfe deines Eclipse/WSAD.

Gruß Axel 


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 11.04.06 - 10:49:38
Das letzte was ich mit apache.jakarta.httpClient gemacht habe war das verarbeiten der xml Datei über die Referenz-Wechselkurse, die täglich von der Europ. Zentral Bank (ECB) als xml veröffentlicht wird.
Jeden Tag um 15:00 Uhr wird eine Methode aufgerufen, die diesen Prozess anstösst.
Funktioniert echt ziemlich problemlos.

Theoretisch hätte ich auch das Programm auf der Seite der ECB schreiben können, dass diese Referenz-Wechselkurse erzeugt.

Da ich mich damit ganz gut auskenne, wäre das vielleicht ein Beitrag für "Show it on Thursday".

Ich kapiere das Problem nicht.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 11.04.06 - 11:04:42
Zitat
Ich kapiere das Problem nicht.

Das Problem ist, dass ich nur für diese Anwendung einen Tomcat aufsetzen müsste. Natürlich muss ich mit der anderen Lösung auch nur für diese Anwendung meinen selbstgebauten Socket-Server aufsetzen (und sogar noch programmieren) aber ich verfolge erstmal diesen Weg weiter, da ich sowas auch noch nie gemacht habe. Wenn meine Lösung einfach bleibt kann ich sie evt. auch an anderen Standorten von uns implementieren lassen. Einen Tomcat-Server aufzusetzen ist dort schwieriger durchzusetzen als eine kleine Javaanwendung laufen zu lassen. Aber DIE gute oder DIE schlechte Lösung gibt es hier sowieso nicht.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 11.04.06 - 16:17:50
irgendwie bin ich zu blöd für die Socket-Geschichte...

Ich habe nun einen Server, der bei einem eingehenden Aufruf einen Clientthread startet, den ich von einem Notesagenten starte. Leider klappt der Ablauf Client schickt was, Server antwortet irgendwie nicht.

Im Clientthread lese ich den InputStream mit
Code:
StringBuffer sb = new StringBuffer(255);
int c;
while ((c = in.read()) != -1) {
sb.append((char) c);
}
Dies ist komischerweise eine Endlosschleife wenn ich vom Client aus dies sende:

Code:
String s = "argument1#argument2";
out.write(s.getBytes());

Wenn ich aber out.close() mache dann läuft mein ClientThread weiter  ???
Zum parsen zerlege ich den StringBuffer.ToString mit dem StringTokenizer. Beim Prüfen der Werte .equals etc hänge ich auch noch fest  >:D >:D >:D

Evt. fehlt

Code:
out.write('\r');
out.write('\n');
bei meinem Client?


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 11.04.06 - 17:34:11
Hallo Mark!

Warum arbeitest du nicht wie in dem Tutorial mit Readline? Im Tutorial ist doch genau deine Anwendung beschrieben. Du brauchst Sie nur herunterladen und die KnockKnock Protocol Klasse abändern. Am einfachsten wäre es wenn du als Kommunikation unr die Universal ID's der Dokumente schickst die überarbeitet werden und du diese dann in deinem Server abarbeitest.

@Axel. Für mich ist Tomcat für so eine mini Sache auf jeden Fall zu groß. Das ganze soll ja dann auch noch perfromant laufen und nicht unbedingt HSP Ende nie fressen. Ausserdem ist so ein kleiner Client viel leichter zu deployen und birgt auch nicht das Risiko, dass ich mir Sicherheitslücken einfange die irgendwo im Tomcat stecken.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 11.04.06 - 18:24:17
Welche Sicherheitsprobleme?
Man braucht den Server ja nicht gegenüber dem Internet zu öffnen und ausserdem hat doch gerade Tomcat eine Menge an Sicherheitsmechanismen wie Authentifizierung, Autorisierung, SSL, uvam bereits implementiert.

Und wie sicher ist bitte der selbstgeschriebene Server?
Es ist doch eindeutig schwieriger dort Sicherheit zu implementieren.

Also so blöd finde ich die Idee mit Tomcat (oder Jetty) gar nicht. Wie gesagt: Beides kann in eine Anwendung embedded werden.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 11.04.06 - 20:48:00
Hab jetzt die KnockKnock Plattform mit Hilfe von Eclipse implementiert.
Ist einfach.
Die 3 Dateien KnockKnockServer, KnockKnockClient und KnockKnockProtocol in 1 Projekt kopieren und kompilieren.
In KnockKnockClient muß man noch die Zeile
kkSocket = new Socket("taranis", 4444);
in
kkSocket = new Socket("127.0.0.1", 4444);
umändern.
Oder dein Server kann per http mit taranis angesprochen werden :-)

Dann die class Datei von Client irgendwohin exportieren.
Den Server in Eclipse starten (geht natürlich auch im debug modus).

Den Client auf der Festplatte von der cmd box aus starten.
Dann wie beschrieben in der Sun Doku.

In jedem Fall ist das Protokoll zu kompliziert. Du benötigst vermutlich nur einen einfachen Command (mit Parametern), der von Notes an den Server geschickt wird und dann schickt der Server die Antwort runter. Die naivste Lösung wäre:
-> Name des Command und jeder Parameter als String, getrennt durch (z.B.) ~. Geht mit Primitivtypen und Strings problemlos. Besser sind imho serialisierte Objekte.

Wenn ich das jetzt richtig verstanden habe, dann verwendet Mehran Habibi in seinem Buch zu Sun Java Dev Examen ein serialsiertes Command Objekt. Dieses wird vom Client an den Server geschickt. Und ich denke, dass dies ein vernünftiger Ansatz ist. Kommt bestimmt noch was von mir zu, wobei ich nicht weiss ob noch heute abend.

Zumindest zeigt das sun beispiel wie es geht. Es ist aber z.B. nicht multithreaded. D.h. es kann immer nur eine Sitzung zu einem User aufmachen. Auch dafür gibts bei Mehran Habibi eine Lsg.

Gruß Axel






Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 12.04.06 - 07:32:08
Hallo Axel!

Zur Ergänzung, in dem Tutorial ist auch der Link auf den Multithread source.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 12.04.06 - 07:51:41
euer Engagement ist großartig, ihr habt wahrscheinlich beide eine fertige Lösung bevor das bei mir läuft  :-[

Im Prinzip nehme ich ja das KlopfKlopf-Protokoll, nur dass ich das nicht in einer extra Klasse ausgelagert habe. Ich möchte natürlich auch gerne verstehen, was ich tue. Und in allen Beispielen, die ich irgendwo gefunden habe, wird ein InputStream in einer while-Schleife ausgelesen:
Code:
while ((c = in.read()) != -1) {
     sb.append((char) c);
}
Wieso ist das dann bei mir eine Endlos-Schleife? Sind alle Beispiele so stark vereinfacht? Oder läuft das nur, wenn die Gegenseite den dazugehörigen Outputstream mit einem Textprompt füllt und nicht programmatisch?
Natürlich läuft es bei mir, wenn ich auf der Gegenseite (im Notesagenten) outputStream.close() mache, aber das habe ich nirgendwo so gesehen.

Die Notesdokument-UID möchte ich übrigens nicht übergeben, da ich meine Mittelschicht gern unabhängig von Notes bauen möchte. D.h. der Server kennt bestimmte Befehle, die dazugehörige Anzahl von Parametern verlangen und gibt dann passende Antworten zurück. So kann ich das Tool dann auch von Nicht-Notesanwendungen nutzen.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 12.04.06 - 07:56:27
und multithreaded brauch ich natürlich auch, sollte bereits drin sein. Ich muss aber noch die maximale Anzahl von parallelen Threads einbauen da Openview nicht beliebig viele Verbindungen mit dem gleichen User erlaubt.

Multithreading:
Code:
ServerSocket httpd = new ServerSocket(port);
while (true) {
Socket socket = httpd.accept();
(new ClientThread(getOVSession(ovserver, ovuser, ovpw), ++calls, socket)).start();



Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 12.04.06 - 09:16:23
ich glaube ich habe meinen Fehler gefunden: Ich benötige überhaupt gar keine while-Schleife im Client oder ClientThread, da der Ablauf der folgende ist:

1. Client C öffnet Socket zum Server
2. Server erstellt neuen Clientthread CT1
3. C schickt eine Zeile mit einem Befehl und Parametern zum CT1
4. CT1 führt den Befehl in Openview aus und schickt eine Zeile als Antwort zurück zu C
5. C empfängt die Antwort und schließt den Socket, daadurch beendet sich CT1

So einfach ist das. Und läuft.
Das ist eben der Nachteil am Cut&Paste programmieren, solange man den Code nicht wirklich versteht passieren oft unerwartete Sachen  O0


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 12.04.06 - 10:47:54
was natürlich ohne die Schleife nicht mehr funktioniert:

Ich kann nicht mehr während einer Client-Sitzung mehrere Befehle abarbeiten, was eigentlich ganz schön wäre. Also muss ich irgendwann doch mal das Problem lösen, wie Client und Server abwechselnd miteinander reden können ohne endlos auf den Abschluss der Eingabe zu warten.
In den Beispielen wurde ja immer System.in o.ä. genutzt und da merkt die Gegenseite scheinbar wann die Eingabe beendet ist (nach einem Enter also \r \n wahrscheinlich). Ich kann dann wohl ein Steuerzeichen definieren, welches die Kommunikation jeweils begrenzt (z.B. ~) da ein im String vorhandenes \n nicht klappte...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 12.04.06 - 11:12:12
Bei mehreren Befehlen würde ich im Namen der Einfachheit für jeden Befehl eine neue Verbindung aufbauen.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 12.04.06 - 11:36:37
ich habe jetzt eine Schleife im ClientThread erstellt:
Code:
while ((inputLine = in.readLine()) != null) {
outputLine = ovp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("bye"))
    break;
    }
In meinem Protocol liefere ich "bye" sobald kein bekannter Befehl gesendet wird

Mein Client liefert nun beliebig viele Befehle (aber ohne Schleife sondern sequentiell) :
Code:
ovSocket = new Socket("myhostname", 3000);
    out = new PrintWriter(ovSocket.getOutputStream(), true);
    in = new BufferedReader(new InputStreamReader(ovSocket
    .getInputStream()));
   
    out.println("set_ackreceipt#Key1");
    System.out.println(in.readLine());
    out.println("set_ackreceipt#Key2");
    System.out.println(in.readLine());
    out.println("remove_ackreceipt#Key1");
    System.out.println(in.readLine());
    out.println("remove_ackreceipt#Key2");
    System.out.println(in.readLine());
    out.println("bye");
    out.close();
    in.close();
    ovSocket.close();

Scheint zu klappen. Vorhin hatte ich ein paar Mal einen Socketabbruch (Software caused connection abort: recv failed) aber seit dem habe ich den Code schon wieder an einigen Stellen verändert und momentan läuft es stabil. Auch von Notes aus.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 12.04.06 - 13:10:19
jetzt habe ich nur noch ein Java- und Openview-spezifisches Problem:

Eine Verbindung zu Openview erhalte ich mit dem Objekt ApiSDSession.getSession(), welches mir wieder ein ApiSDSession liefert.
Nun gibt es zwar die Methode closeConnection(), nicht aber einen Test, ob die Verbindung noch aktiv ist. Nach einer Stunde Leerlauf (oder bei Server- oder Netzwerkproblemen) wird die Session aber abgebaut. Wie und wo in meinem Konstrukt aus Server, ClientThreads und Protocol prüfe ich nun, ob eine Session noch da ist und wenn nicht erstelle ich automatisch eine neue?
Das Objekt ApiSDSession ist ja auch noch vorhanden, wenn die Verbindung nicht mehr vorhanden ist. Sobald ich aber eine Methode nutze, die auf die Session zugreift werde ich wohl irgendeinen Laufzeitfehler bekommen.
Das heisst wohl, dass ich in irgendeiner catch-Bedingung die Logik platzieren muss, wieder eine neue Session aufzubauen?


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 12.04.06 - 13:43:05
Ich würde die Session grundsätzlich nach Gebrauch explizit schliessen.
Vermutlich die Session in einer eigenen Klasse wrappern. Im Problemfall kannst du ja auch auf Exceptions reagieren, die kommen, wenn die Connection nicht da ist, du aber die entsprechenden Methoden aufrufst. Du wirst vermutlich keine Runtime-Exception bekommen sondern eine checked Exception. Trotzdem besser die Exception schliessen.
Aber auch Runtime-Exceptions kann man ja abfangen (catch (Throwable t)
Ganz elegant wäre die Lösung über einen Connection Pool. Aber das kann schwierig sein. V.a. wenn du den Source code nicht hast. Aber vielleicht hat der Hersteller schon so etwas.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 12.04.06 - 15:23:44
die Exception, die ich nach einem Timeout bekomme sieht so aus:

Zitat
Your session on the server has timed out. Click OK to log on, then try again.

Ist immer lustig, wenn in Backend-Code Frontend-Fehlermeldungen kommen  ;D

Wenn ich die abfangen möchte, muss ich dann exception.getMessage() mit diesem String vergleichen? Leider gibt es zur web-api nicht so eine gute Dokumentation...
Ich könnte ja in meiner zentralen Connection-Verwaltung eine Methode einbauen, die session.getUsername macht. Sollte hier irgendein Fehler auftreten würde ich dann einfach eine neue Session aufmachen und die dann zurückgeben.
Finde ich nicht so elegant, aber anders scheint das wohl nicht zu gehen...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 12.04.06 - 16:55:02
Hm. Du solltest diese Exception auf dem Server in eine RemoteException packen. Man kann ja seit 1.3 Exceptions chainen. Der Server ist Client von OpenView
Code:
try { } catch(TimeoutException te) {
throw new RemoteException ("OpenViewConnection failed", te); }
oder du machst eine neue Klasse OpenViewConnectionException extends RemoteException
so ungefähr.
Meine Idee mit dem Wrapper war Quatsch. Eine zentrale ConnectionFactory ist ok würd ich jetzt sagen.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 13.04.06 - 05:59:06
Was ich da gesagt habe, ist bezogen auf deine Idee dort reine Strings zu übertragen kompletter Blödsinn.
Versuch das mal am WE mit serialisierbaren Command-Objekten.
RMI basiert übrigens auf Sockets. Dort gibt es einen übersichtlichen Mechanismus für Exceptions. Gehen tut es also.  ;D


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 09:15:44
meine Aufrufe nach Openview will ich nun in einer einzigen Session bündeln. Dafür erstelle ich eine Klasse, die bei jeder Verbindung genutzt werden soll, damit nie mehr als eine Session geöffnet ist. Daher wollte ich das als Singleton machen, aber irgendwie ist mir das wieder etwas verwässert. Haut das so hin? Erstmal der Code:

Code:
public class OV {
private static OV instance = null;

private ApiSDSession session;

private String srv;

private String usr;

private String pwd;

public OV(String srv, String usr, String pwd) {
this.srv = srv;
this.usr = usr;
this.pwd = pwd;

instance = this;
}

public static ApiSDSession getSession() {
try {
// check if session is usable
IBrandHome dummy = instance.session.getBrandHome();
return instance.session;

} catch (Exception e) {
// dummy not available that means no valid session
try {
instance.session = ApiSDSession.openSession(instance.srv,
instance.usr, instance.pwd);
return instance.session;
} catch (Exception ex) {
e.printStackTrace();
return null;
}
}
}

public static void disconnect() {
instance.session.closeConnection();
}

public static void connect() {
try {
instance.session = ApiSDSession.openSession(instance.srv,
instance.usr, instance.pwd);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Die Nutzung ist folgende: Wenn der Server hochfährt übergibt er die Anmeldedaten an diese Klasse:

Code:
OV ov = new OV(args[0], args[1], args[2]);
ohne hier mehr damit zu machen.

Bei jedem Zugriff auf Openview wird in meinem Protocol nun folgendes aufgerufen:

OV.connect();
Nutzung der session über OV.getSession()
OV.disconnect();

Ich erzeuge also im Server eine statische Instanz und nutze diese dann später über statische Aufrufe der Klasse. Macht man das so oder ist das irgendwie komisch? Beim Singleton holt man sich ja eigentlich eine Instanz, die innerhalb des Singletons immer das gleiche statische Objekt liefert!?

(hab noch mal den Konstruktor geändert...)


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 13.04.06 - 09:50:10
Wenn ich dich richtig verstehe, dann würde dies zur Folge haben, dass du multithreading vergessen kannst  ???

Singleton implementierst du mit Java ungefähr so:


Code:
public class OV {

private static OV inst = null;

// constructors sind private.
private OV() {}

private OV(String srv, String usr, String pwd) {
this.srv = srv;
this.usr = usr;
this.pwd = pwd;
}


// hierüber bekommt man das Singleton.
public static OV getInst(String srv, String usr, String pwd) {
 if (OV.inst = null) {
   OV.inst = new OV(srv, usr, pwd);
 }
 return OV.inst;
}
}

Gibt noch ein paar gotchas mit multithreading und serialisierten Objekten, die z.B. in Joshua Blochs, Effective Java stehen.

Aber, warum?
Die Factory für die Session Objekte kann man vielleicht als Singleton erstellen. Aber von den Connections selber können doch wohl mehrere gleichzeitig aktiv sein, oder?

Btw. sind IOC frameworks (z.B. spring) wirklich viel besser als klassische Architekturen, die immer darauf hinauslaufen, dass es da diese ganzen Singleton-Factories gibt, die über den Source Code verstreut aufgerufen werden.
Und dann ändere mal den Construktor der Singleton-Factory... (ist mir oft passiert. macht keinen Spaß).




Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 10:17:55
multithreading heißt für mich, dass von verschiedenen Rechnern aus gleichzeitig Aktionen durchgeführt werden können. Ob Openview schneller arbeitet wenn ich von meinem Server 7 Befehle innerhalb einer Session parallel anstosse oder das gleiche innerhalb von 7 parallelen Sessions weiß ich nicht. Für mich würde aber der erste Fall von beiden auch ok sein. Es wäre dann so, als würde ich meinen Openview-Client öffnen (1 Session) aber 7 Fenster gleichzeitig öffnen und in jedem was anderes machen.

Bei der untigen Singleton-Implementierung stört mich, dass ich über getInstance jedesmal User, Password etc mitschicken muss. Ich wollte das einmalig machen und dann später nur noch connect und disconnect nutzen.

Hab nun auch mal log4j eingebunden, dann wird mir das endlich mal transparenter was wirklich abläuft...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 13.04.06 - 11:16:11
Aber beim ersten Aufruf sind diese Parameter notwendig.

Du kannst so was hinzufügen:
Es muß über die getInst mit Parametern initialisiert werden, kann aber ohne Parameter geholt werden.

Code:
public static OV getInst() throws InstantiationException {

if (OV.inst == null) {
   throw new InstantiationException ("Der Singleton OW kann von aussen nur über den Aufruf Ov.getInst(String, String, String) initialisiert werden.")
   
}
return OV.inst;
}

Aber Singleton in Java ist wirklich so.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 11:31:06
und wenn ich den Code so wie von mir beschrieben verwende? Gibt es dann Probleme?


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 13.04.06 - 11:40:18
Multithreaded drauf zugreifen?
Ob das geht, das hängt von openView ab.
Das mußt du testen oder du kannst vermutlich auch die Entwickler fragen. Die sollten das wissen.

Gruß Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 12:49:48
meine 'Serialisierung' mache ich durch aneinanderketten von Strings und einem Trennzeichen ('#' im Moment).
Code:
StringTokenizer splitter = new StringTokenizer(result, SEP);
Vector v = new Vector(splitter.countTokens());
while (splitter.hasMoreTokens()) {
v.addElement(splitter.nextToken());
}
mit v.elementAt(0) z.B. hole ich mir dann die Werte. Das ist aber irgendwie blöd, da bei null-Werten (also zwei ## hintereinander) der Tokenizer nix liefert und dann meine Anzahl von Elementen variiert. Kann Java keinen split() wie in Javascript oder Lotusscript? Ich finde irgendwie nix dazu pbwohl das doch sicher jeder ständig benutzt...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 13.04.06 - 13:47:18
meine 'Serialisierung' mache ich durch aneinanderketten von Strings und einem Trennzeichen ('#' im Moment).
Ich poste mal ein Beispiel mit serialisierten Objekten über Sockets. Aus meiner Sicht ist das objektiv einfacher.

Seit java 1.4 existiert eine split Methode in java.lang.String. Laß dir von dem regex nicht abschrecken. Das Beispiel sollte auf deinen Fall passen:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#split(java.lang.String)



Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 14:48:03
das ist doch genau das, was ich gesucht habe...

Leider hab ich natürlich vergessen, dass ich erst nächste Woche die Server auf Domino 7 upgrade und dass die Clients auf 6.0.3 bleiben :-(

Zitat
error message: java.lang.NoSuchMethodError: java.lang.String: method split(Ljava/lang/String;)[Ljava/lang/String; not found

Mein Objekt Server läuft zwar in einer eigenen VM, aber die Clients (also Notesagenten) müssen ja die Antwort auswerten...

Nun nehme ich wohl dieses hier (Quelle: http://forum.java.sun.com/thread.jspa?threadID=646861&messageID=3808970

Code:
/**
 * Split string into multiple strings
 * @param original      Original string
 * @param separator     Separator string in original string
 * @return              Splitted string array
 */
private String[] split(String original, String separator) {
    Vector nodes = new Vector();
 
    // Parse nodes into vector
    int index = original.indexOf(separator);
    while(index>=0) {
        nodes.addElement( original.substring(0, index) );
        original = original.substring(index+separator.length());
        index = original.indexOf(separator);
    }
    // Get the last node
    nodes.addElement( original );
 
    // Create splitted string array
    String[] result = new String[ nodes.size() ];
    if( nodes.size()>0 ) {
        for(int loop=0; loop<nodes.size(); loop++)
        result[loop] = (String)nodes.elementAt(loop);
    }
    return result;
}


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 13.04.06 - 15:13:19
... oder jakarta.commons. Da hätte ich als nächstes gesucht:
http://jakarta.apache.org/commons/lang/api-release/org/apache/commons/lang/StringUtils.html
Da gibt es auch eine split Methode.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 15:57:44
jaaaaa, mehr davon  :D

sowas suchte ich doch. In Notes weiß ich ja, wo ich was finde, aber in Java ist alles so groß und unübersichtlich, da muss ich erstmal Erfahrungen sammeln, was man immer einbaut und wo man es findet. Wie z.B. log4j, das ist genauso wie OpenLog in Notes ein absolutes muss in jeder Anwendung.
(es gibt ja auch log4LS von Johan Känngard analog zu log4j aber da gefällt mir OpenLog von Robincheaux  ;D besser)


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 16:09:32
eigentlich läuft es nun. Aber schon im ersten Belastungstest komme ich an irgendwelche Socketgrenzen  >:D

Code:
while (true) {
Socket socket = httpd.accept();
(new ClientThread(socket)).start();
}

nach etwa 6 mal Thread starten und wieder beenden bleibt er bei httpd.accept() endlos stehen und auch meine beiden Testclients warten nun endlos. Keine Fehlermeldung, aber auch keine neue Socketverbindung   :'(

Gibts da ne Begrenzung inWindows oder in TCP oder im ServerSocket-Objekt?


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 16:48:47
vielleicht ist es irgendein Wondows-Hotfix gegen DoS !?

Naja frohe Ostern und bis nächste Woche  O0


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 13.04.06 - 17:52:43
jaaaaa, mehr davon  :D
jakarta-commons ist immer eine gute Anlaufstelle für grundlegende Sachen.
Hani Suleiman hat zwar ca. 719 bösartige Bemerkungen über jakarta commons Programmierer gemacht, aber ich finde da übertreibt er ein bischen.

Solltest du irgendwann einmal etwas mit Daten in Java machen, komme nicht auf den Gedanken, dass mit den Klassen java.util.Calendar (inklusive aller konkreten Implementierer wie java.util.GregorianCalendar), java.util.Date oder java.sql.Date alleine zu machen. Benutze auf jeden Fall JodaTime.

Gibts da ne Begrenzung inWindows oder in TCP oder im ServerSocket-Objekt?
Nein. Du hast irgendwas falsch gemacht. Deshalb insistiere ich ja so auf Objekte austauschen und nicht: Ha-Ha Programmierung ist einfach. Alles sind Strings. Das klappt in aus meiner Erfahrung in 80% der Fälle nicht.
RMI, EJB Implementierungen und eine Menge weiterer Sachen basieren auch java.net.Socket-Zeugs.

Gruß Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 13.04.06 - 19:53:00
ich mache nie etwas falsch.  ;D

naja, jedenfalls muss hier der Fehler woanders liegen, da es etwa 3x nacheinander funktioniert und ab da gar nicht mehr.
Der Befehl ServerSocket.accept() tut einfach nichts mehr und irgendwann gab es mal ein Windows-Hotfix, welches mehrere Socket-Aufrufe blockt, da eine DoS-Attacke verhindert werden soll. Anders kann ich es mir nicht erklären, vielleicht finde ich bei MSDN was...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 15.04.06 - 08:03:28
Mark,

ich finde es absolut faszinierend, dass du offenbar in diesem Projektstatus Mehrfachaufrufe in deinen Junit-Tests hast.   :D

Ich finde das Thema interessant und arbeite an einen kleinen RemoteCommand Beispiel über Sockets.

Ich möchte, dass diese Anfragen an die Businesslogik des Remote Service als Objekt übertragen werden (und das wird auch klappen).
Benutze dafür das Command Pattern.
Ist halb fertig, wird klappen und ist für solche Aufgaben wiederverwendbar.








Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 18.04.06 - 11:32:14
ich konnte den Fehler noch nicht identifizieren. Heute trat er bei einem Belastungstest nicht auf. (Schade, ich wollte ihn mit TCPView umzingeln)
Bei Microsoft gibt es diverse Registry-Parameter und HotFixes, die das Verbinden und erneut verbinden über Sockets beeinflussen, aber ohne genaiuen Fehler komme ich da nicht weiter. Ich habe meinen PrintWritern nun noch ein flush() mitgegeben, da der OutputStream aber nicht Bufferd ist erscheint mir das irgendwie sinnlos...



Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 18.04.06 - 15:59:11
das ist doch alles  >:( ??? :-[ :'(

ich bekomme immer wieder unregelmäßig komische Fehler, ich werde wohl doch über einen Tomcat-Server gehen. Auf die gleiche Arie mit RMI habe ich keine Lust, da ich nicht ausschließen kann, dass ich dann wieder die gleichen Socket-Probleme bekomme...

Ich habe zwar bereits ein paar JSPs als Vorlage, die auf Openview zugreifen, allerdings möchte ich ja gar keine Webseiten aufrufen sondern direkt die Servlets (oder Webservices?) ansprechen. Da weiß ich momentan wieder gar nicht wo ich anfangen soll...
Es gibt wohl eine fertige Session-Bean, die ich zum einloggen nehmen kann. Naja konkretes kommt später, nun muss ich mich erstmal zurechtfinden...


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 19.04.06 - 11:18:47
ich habe nun eine meiner benötigten Funktionen als JSP implementiert, das klappt manuell schon.
Wie ich das nun aber praktisch mache ist wmir noch nicht so klar. Momentan öffne ich eine Login.jsp, die eine Session-Bean erstellt und dafür User und Passwort verlangt (Eingabe in Webseite). Danach kann ich dann die nächste JSP aufrufen, die meine gewünschte Funktion in Openview durchführt. Wie mache ich das nun, wenn ein Notesagent die Aktionen aufrufen soll?

Ich könnte natürlich das einloggen im Code mit verwursten und direkt eine einzige JSP aufrufen die jeweils die Funktion ausführt die ich gerade benötige. Dann könnte ich also statt JSP gleich ein Servlet nehmen, welches ich dann direkt aufrufe?
Und dann über post oder get, was ist da besser aus Notesagent raus?  ???
Nochmal als Zusammenfassung für Thread-Fremde:

Ich habe einen Tomcat-Server, der über eine API Funktionen in HP Openview Servicedesk ausführen soll. Ansprechen möchte ich die Funktionen über eine Notesdatenbank. Die Ergebnisse sollen dann in Dokumenten der Datenbank sichtbar sein.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 19.04.06 - 11:48:40
Hallo Mark!

Wie ich schonmal gesagt habe, JSP ist hier nicht geeignet, da JSP im J2EE Umfeld für die Präsentation zuständig ist, also im Normalfall jede Menge HTML enthält. Scriptlets (also Java Code im JSP) ist schlechter Stil und sollte man nicht haben, obwohl ich zugeben muß, dass ich das vor Jahren auch so gemacht habe. Du solltest also auf jeden Fall Servlets verwenden. Übrigens können Servlets alles, was auch in JSP's machbar ist, da JSP während der Umwandlung in Servlets verwandelt werden. Du kannst deine Parameter sicher genauso übergeben wie es ein Browsermacht und zwar hinter deinem Url mit "Url?Parameter1=XX&Parameter2=XX" Diese Parameter kannst du dann im Servlet wieder einlesen.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 19.04.06 - 14:29:44
Hi Mark,

ich bastele zu Hause (wenig Zeit, Ostern weitgehend weg von meinem Computer) an einer ultimativen Server Socket Lösung. Vielleicht klappts heute.
Nimm für dieses Tomcat Zeug HttpClient von jakarta Commons. Ich poste noch bis 17:00 Uhr etwas, das zumindest als Gedankenstütze für mich dienen kann.

Ansonsten würde ich Ralf zustimmen, aber wenn du das schon mal soweit hast...

Jakarta-commons kann Authentifizierung und du brauchst dich vermutlich gar nicht mehr darum kümmern. Ich habs jedenfalls mal für einen Dresdenerbank-Service hingekriegt und da mußte man sich auch authentifizieren.

Kann das heute noch mal gegen Tomcat ausprobieren.

Gruß Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 19.04.06 - 15:24:45
ok, ich konzentriere mich dann auf Servlets...
Irgendwie werden diese Webgeschichten im Eclipse WTP nicht so schön dargestellt, das war die einzige Domäne, wo NetBeans mir besser gefiel. Ich baue also ein neues Dynamic Web Project, erstelle dort drin ein paar Servlets und mache Run on Server 'marks Tomcat'  8)
Den http-Client von jakarta commons baue ich dann als Client in meinen Notesagenten ein? Nicht dass ich dann wieder da lande, wo ich herkomme, nämlich bei 'error cleaning up agent threads' und som Zeugs  >:D


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 19.04.06 - 16:09:51
ok, ich konzentriere mich dann auf Servlets...
Irgendwie werden diese Webgeschichten im Eclipse WTP nicht so schön dargestellt, das war die einzige Domäne, wo NetBeans mir besser gefiel.
Ich verwende myEclipse professional Edition (ca. 49 Euro pro Jahr mit updates). Ich überlege mir, ob ich mir Intelij IDEA kaufen soll (495 Euro).

Zitat
Den http-Client von jakarta commons baue ich dann als Client in meinen Notesagenten ein? Nicht dass ich dann wieder da lande, wo ich herkomme, nämlich bei 'error cleaning up agent threads' und som Zeugs  >:D
Ich würds erstmal als zweites Eclipse Projekt machen (neben dem Tomcat Projekt).


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 19.04.06 - 16:16:24
Zitat
Ich würds erstmal als zweites Eclipse Projekt machen (neben dem Tomcat Projekt).
Das hilft mir leider nicht. Die Notesdatenbank inkl. aller Funktionalität ist fertig, es fehlt nur noch die Schnittstelle Notes <-> Openview.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 19.04.06 - 18:27:58
wieso. Du kannst allein schon im Namen von einfacheren Debugging erstmal in Eclipse den Code für die Schnittstelle erzeugen? 


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 19.04.06 - 18:34:06
Hier sind jedenfalls die Abhängigkeiten.
http://jakarta.apache.org/commons/httpclient/dependencies.html
Diese jars dort und das jar von HttpClient selbst gehören in das lib/ext Verzeichnis der JVM des Servers (oder wo immer das auch nur testweise laufen soll).
Es geht in jedem Fall mit 1.4 und ich hoffe auch mit 1.3.
Sonst müsstest du die Klassen in java.net benutzen. Geht auch.

apache.jakarta HttpClient ist aber einfacher.

Gruß Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 19.04.06 - 20:04:14
das entwickeln mache ich natürlich in Eclipse, da haben wir aneinander vorbei gedacht...
Bloß das Einbinden von großen jars in Notes wollte ich eigentlich vermeiden. Aber wenn ich die auf dem Server ins JVM-Verzeichnis lege wird es wohl gehen, wenn nicht wieder Speicherprobleme auftreten oder agent thread Fehler nerven. Dann muss ich aber alle meine Agenten auf dem Server laufen lassen...Und dann hätte ich mir womöglich alles schenken können und einfach die Openview web-api.jar auf den Server legen können. Naja, man lernt ja trotzdem immer was dazu. Und Sonntag werde ich unsere Server auf 7.0.1 aufrüsten, dann ist JRE 1.4 kein Problem mehr serverseitig.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 19.04.06 - 23:01:37
Das geht natürlich auch Clientseitig.

Hier ist jedenfalls Beispielcode für httpClient:
Attachment in Zip umbenennen. Beinhaltet 4 Klassen.
verwendete jars:
commons-codec-1.3.jar
commons-httpclient-3.0.jar
commons-logging-jar
commons-logging-api.jar (?)
dom4j-1.6.1.jar
jaxen-1.1-beta-6.jar (im lib des dom4j downloads).

Einfach ExchangeRateService starten (hat eine main-Methode).
Falls du hinter einer Firewall sitzt, musst du noch das ReverseProxyBean initialisieren. In der main von ExchangeRateService die 2 neuen Zeilen einfügen:
Code:
public static void main (String args[]) {
ExchangeRateService exchRateService = new ExchangeRateService();
// neu
ReverseProxyBean revProxyBean = new ReverseProxyBean("host", 8080, "username", "password");
exchRateService.setReverseProxyBean(revProxyBean);
// neu ende

Dieser code sollte eine Zeile der aktuellen Referenzwechselkurse der europ. Zentr.bank zurückgegeben. (als Map wenn ich mich recht erinnere).
dom4j ist btw auch eine wirklich einfach zu benutzende xml api.

Das funktioniert noch nicht gegen einen Server der Authentifizierung verlangt. Das kommt morgen.

Gruß Axel


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 20.04.06 - 05:19:07
Hab auf die schnelle doch noch was gefunden.
Versuche vielleicht das hier:
Code:
Credentials defaultcreds = new UsernamePasswordCredentials(
usernameServer, passwordServer);
client.getState().setCredentials(AuthScope.ANY, defaultcreds);
in die Methode
buildRequestHeader() von ExchangeRateService zu packen (am Schluss. Ist aber egal.

empfohlene Schritte:
1. Eclipse Projekt aufsetzen
2. jars runterladen.
3. In Projekt Classpath die genannten jars (aus: commons-httpclient, commons-codec-1.3, commons-logging-1.0.4 sowie dom4j-1.6.1) importieren.
4. Das oben angehängte .jpg runterladen und in zip umbenennen.
5. Die 4 Dateien im zip in das src-Verzeichnis des Projektes importieren.
6. Gegebenfalls oben angesprochene Firewall-Änderung durchführen.
7. Testen d.h. ExchangeRateService starten.
8. An deine Gegebenenheiten anpassen (evtl. mit oben angesprochener Änderung mit Authentifzierung).



Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 20.04.06 - 06:56:41
Ich hoffe das ist klar.
Der Teil ist btw. ein Beispiel für definitiv übles Errorhandling von mir:
Code:
org.w3c.dom.Document doc = db.parse(is);

return parseTodaysExchangeRateBeansFromXml (doc);

} catch (Exception e) {
String errMsg = "Die URL ist nicht erreichbar:" + urlEcbDaily;

throw new WebRetrievalException(errMsg, e);

}


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 20.04.06 - 16:48:13
ich habe nun ein Servlet auf Tomcat laufen, welches meine gewünschten Befehle in Openview ausführt.
Um auf Clientseite Java loszuwerden nutze ich nun Microsoft ActiveX (http://atnotes.de/index.php?topic=28468.msg180071#msg180071. Java und Notes-Client ist eben noch nicht so stabil.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 20.04.06 - 16:50:48
Ist es doch. Nur eben ein bischen kompliziert. Ich werde mal ein Beispiel posten.
Allerdings für Notes 7.0.
Wir haben allerdings auch eine Anwendung laufen, die mit Notes 5.0 per http mit einem Tomcat Server per xml kommuniziert. Nur mit den Sun java.net Klassen von java1.1 und den xml libraries von notes auf java1.1. Und das macht keinen Spaß.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 28.04.06 - 22:52:02
Ich hab jetzt mal eine SocketServer Umgebung durchgecodet.
Client von CMD-Console und Server von Eclipse starten macht keine Probleme. Dh. läuft.

Morgen packe ich den Client in einen Notes Agenten.

Falls sich jemand dafür interessiert:
1. Das Error-Handling ist sicher nicht ausgereift.
2. Das Command Framework ist schlecht. Ich wollte es jetzt nicht direkt neu programmieren. Mach das irgendwann noch besser.
3. Was tun?
a) das attachte File in clientObjects.jar umbenennen und in ein Verzeichnis tun (z.B. C:\temp)
b) Die einzelnen Klassen des jars in ein Eclipse Projekt importieren.
c) In Eclipse die Klasse de.aja.server.SocketServer starten. (in clientObjects.jar sind sowohl die Client als auch die Server-Klassen)
d) in Windows (z.B.) clientObjects.jar von der Kommandozeile starten:
(man hat dann quasi 2 Java Programme 1 Client und 1 Server)
Code:
C:\TEMP>java -jar clientObjects.jar
cba

C:\TEMP>java -jar clientObjects.jar
cba

C:\TEMP>java -jar clientObjects.jar
cba
Man kann es mehrmals aufrufen.
Im Sourcecode steht, was passiert.

1. Der Client erzeugt ein Objekt.
2. Der Client schickt das Objekt als serialisierten Stream an den Server.
3. Der Server verarbeitet das Objekt weiter. (ruft Methode excecute auf).
4. Der Server sendet ein Antwort-Objekt an den Client zurück.
5. Der Client ruft eine Methode des empfangenen Objekts auf.

Wie gesagt: Marc-> Auf die Art kannst du (oder jemand anders) Objekte in Notes erzeugen, an den hier enthaltenen SocketServer schicken. Der SocketServer kann dann irgendwelche Klassen aufrufen (z.B. dieses openView Zeugs) und  ein Response Objekt zurücksenden
... und das kann man in Notes wieder empfangen.

DAS IST ZWAR ALLES EIN BISCHEN SCHLUDRIG RUNTERGESCHRIEBEN.
ABER: Wär schön wenn sich jemand für interessieren würde. Ich hab die Idee verschiedene Remote-Aufrufe aus Notes in Java sauber durchzuprogrammieren und in Show-Code-on Thursday (oder wie immer diese Rocky Oliver Initiative heisst) publizieren.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 02.05.06 - 07:53:40
da sind ein paar interessante Details drin, z.B. die Weitergabe von Objekten...

Ich muss erst mal mein konkretes Problem lösen bevor ich mir das genauer ansehen kann. Die Problematik bei mir sind die Openview-Zugriffe, da ich die Connections nicht richtig verwalten kann. Die API hat zwar einen connect-Befehl, aber keine Prüfung, ob die aktuelle Session noch gültig ist. Nach 30 min gibts einen Timeout, danach kann ich die Session nicht mehr nutzen. Nun muss ich wohl einen Timerthread einbauen, der alle 20min einen Dummyzugriff macht um den Timeout zu umgehen. Alles irgendwie unelegant, aber die API liefert einfach nix vernünftiges.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 02.05.06 - 08:04:30
@Axel!

Soll dein Attachment wirklich ein Txt sein. Wenn ich es aufmache sehe ich zwar teilweise Java Code aber auch ziemlichen Mist. Sieht irgendwie nicht nach einem Textfile aus.

Grüße

Ralf

@Mark Liefert die Session einen Fehler, wenn du auf Sie zugreifst und sie bereits abgelaufen ist?

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 02.05.06 - 08:24:25
ja sie liefert einen Fehler  ;D Der Inhalt ist in etwa so:

Zitat
Your session has timed out. Please click OK to continue

Das entspricht auch dem Verhalten im normalen Client von Openview Servicedesk. Dort erscheint dann auch ein Popup, wo man OK klickt und danach erneut Username und PW angeben kann.

Ich hatte probiert im Falle eines Fehlers eine neue Session zu erstellen, dies klappte aber nicht vernünftig:

Code:
try {

// check if session is usable
@SuppressWarnings("unused")
IBrandHome dummy = OV.session.getBrandHome();

return OV.session;
} catch (Exception e) {
// dummy not available that means no valid session

try {
System.out
.println("OVSD session not available, maybe timed out..."); //$NON-NLS-1$
OV.session.finalize();
OV.session = ApiSDSession.openSession(OV.SRV, OV.USR, OV.PWD);
System.out.println("Created new session " //$NON-NLS-1$
+ OV.session.getWorkflowSession());
return OV.session;
} catch (Exception ex) {
e.printStackTrace();
return null;
} catch (Throwable ex) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}

Laut Log wurde hierdurch auch 1-2 Mal eine neue Session aufgebaut. Wenn ich aber einen Tag warte bekomme ich keine neue Session mehr hin mit diesem Code.
Ich habe mir das mal mit JAD angeschaut, die ganze Session-Verwaltuing ist recht komplex, mit zur Laufzeit kompilierten Proxies etc.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 02.05.06 - 08:29:15
Du hast meiner Meinung nach einen Fehler in deinem Code:

Du schreibst zweimals irrtümlich e.printStackTrace() wo es meiner Meinung nach aber ex.printStackTrace() heissen sollte. Eventuell verstehst du deshalb den Fehler nicht.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 02.05.06 - 08:41:27
@Ralf: Ich hab oben geschrieben->
3. Was tun?
a) das attachte File in clientObjects.jar umbenennen und in ein Verzeichnis tun (z.B. C:\temp)
Geht das nicht?

Mark: Imho solltest du erstmal die Session einfach nach JEDEM GEBRAUCH SOFORT SCHLIESSEN.
Das ist aber nur möglich, wenn du ein stateless Protokoll benutzt (wie in meinem Beispiel).
Dort gibt es einen Request und darauf direkt einen Response. Vor dem Absenden des Responses kann der Server die Connection auf Openview SCHLIESSEN (GOOD THING).

Alles andere sollte man vernünftig in einem eigens dafür programmierten ConnectionPool implementieren und nicht mit dem Anwendungscode verkoppeln! SERIOUS.
Das mit dem ConnectionPool würd ich erstmal lassen. Man kann sowas aber später bei Bedarf dazuprogrammieren und zwar genau dann wenn die Performance nicht das Gelbe ist, weil z.B. der Aufbau der Connection eine Menge Ressourcen beansprucht.







Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 02.05.06 - 08:46:22
@Axel Sorry habe ich überlesen!

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 02.05.06 - 08:54:03
das mit dem SOFORT SCHLIESSEN hatten wir eigentlich bereits abgearbeitet. Wenn ich 5x hintereinander in kurzer Folge eine Session in Openview öffne und schließe bekomme ich keine weiteren Sessions mehr. Ursache ist wahrscheinlich dass ein User nur 5 Sessioins gleichzeitig öffnen darf und sie nach dem Schließen noch eine kurze Zeit gecached werden.
Du darfst hier die Sessions der Webapi von Openview auch nicht mit Connections auf eine Datenbank verwechseln. Dieses Openviewteil macht eine Menge an Connection-Pooling etc. bereits versteckt in der Blackbox 'Webapi'.

Irgendwo tief im Quelltext (7000 Klassen, 20 MB Quellcode) habe ich nun auch die Methode isLoggedOn() gefunden, die ist zwar public aber ich habe noch keinen Weg gefunden, da von außen ranzukommen.

@Ralf: Mein Errorhandling ist natürlich falsch dort, mal sehen was ich bekomme wenn ich das korrigiere.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 02.05.06 - 09:39:23
Wenn ich 5x hintereinander in kurzer Folge eine Session in Openview öffne und schließe bekomme ich keine weiteren Sessions mehr.
Warum sollte man das tun in kurzer Folge hintereinander?
Du verbindest 1x und holst dir alle Daten, die du benötigst? Oder?

Das mit dem eigenen ConnectionPool in OpenView ist natürlich vielleicht ein Argument.
Aber mit expliziten closen der Session sollte die Connection dann an den Pool zurückgegeben werden. Ich glaub das Problem ist das "5 mal in kurzer Folge hintereinander" und das brauchst du imho nicht, wenn du die Kommunikation mit einem stateless protocol regelst.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Ralf_M_Petter am 02.05.06 - 09:43:28
@mark!

Sorry, aber habt ihr keinen Support Vertrag, bei diesem OpenView. Wenn du nach ein paar mal öffnen und schliessen einer Connection keine Verbindung mehr bekommt, ist das ganz klar ein Fehler, egal ob hier ein Connection Pool im Einsatz ist oder nicht. Ich denke mal, dass du eventuell, dass ganze mal in einem Openview Forum posten solltest. Da wir hier ja ein Problem haben, dass jetzt nicht mehr mit Domino zusammenhängt. Bitte jetzt nicht so verstehen, dass ich den Thread abdrehen will aber weder Axel noch ich haben Openview Kenntnisse.

Grüße

Ralf


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 02.05.06 - 09:53:06
Wenn Mark das kurz hintereinander macht, weil er ein unnötig komplexes statefull protocol benutzt, dann würd ich erstmal das Protokoll vereinfachen, bevor man sich an den Hersteller wendet.
SERIOUS.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 02.05.06 - 10:12:29
ja, mit Notes hat das allemal nicht mehr viel zu tun hier  ^-^ Im HP-Forum hat mir niemand geantwortet weil niemand auf der Welt solche Sachen damit macht wie ich  :-[ Eigentlich wird die web-api innerhalb von den Openview Servicepages genutzt, das ist eine Webanwendung aus JSPs etc. Support gibts für solche Eigenlösungen, wie ich sie mache, nicht. Und einen HP Berater der sowas macht bezahlt hier ganz sicher niemand. Schließlich ist ja der vorgegebene Ansatz: Meine Anwendungen sollen alles können, dürfen aber keine Kosten verursachen. Und die Kosten für meine Arbeitszeit werden einfach nicht mitgezählt weil ehda. Aber die Feinheiten des modernen Managements haben auch nix mit Notes zu tun  >:D

Aber das stateful/stateless Protokoll sagt mir irgendwie nix, ich habe ganz einfach ein einziges zentrales Session-Objekt, dass einmalig eine Session öffnet und wieder schließt (oder eben nicht schließt). Was ist daran komplex? Alle meine n Clients nutzen die gleiche Instanz dieser Session (muss auch so sein wegen Lizenzen etc) und wenn 5 Aufrufe in sehr kurzer Abfolge auftreten dann geht an- und abmelden eben nicht egal ob state oder nix state  ???

Ich könnte eine Zwischenschicht bauen, die die Befehle in Mauszeigerbewegungen umsetzt und dann einen normalen Openview-Client fernsteuert. Tritt hier ein Timeout auf wird einfach auf die OK-Schaltfläche geklickt  ;D 

ok, ich denke ich bekomme das zum Laufen wenn ich alle 20min einen Dummybefehl absetze so dass kein Timeout mehr auftritt. Dann bekomme ich aber wahrscheinlich ab und zu Probleme wenn die Session dann mal in einem Wartungsfenster beendet wird oder so. Ist nicht gut aber bei diesen Vorgaben immerhin ein Workaround (ja wir sind ja voll auf ITIL da reicht sowas dann)
 O0



Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 02.05.06 - 10:46:43
ja, mit Notes hat das allemal nicht mehr viel zu tun hier
Ich find das sind ziemlich grundlegende Integrationsfragen einer Notes Plattform in eine Corporate IT Infrastruktur. Ich werde jedenfalls weiter an meinem Integrationsframework arbeiten.

ich habe ganz einfach ein einziges zentrales Session-Objekt, dass einmalig eine Session öffnet und wieder schließt (oder eben nicht schließt). Was ist daran komplex? Alle meine n Clients nutzen die gleiche Instanz dieser Session (muss auch so sein wegen Lizenzen etc) und wenn 5 Aufrufe in sehr kurzer Abfolge auftreten dann geht an- und abmelden eben nicht egal ob state oder nix state  ???
Das wußte ich nicht. Hab gemutmaßt, dass du für jede Session 5 mal die Verbindungen auf und zumachst, weil das Protokoll so kompliziert ist. Zugegebenermassen ziemlich gemutmaßt. Sorry.
Es sollte aber irgendwie eine bessere Lösung geben. Weiss aber z.Zt. auch nicht weiter und das ist ziemlich openView spezifisch. Aber solche spezifischen Probleme treten halt immer wieder auf.


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: Mark³ am 03.05.06 - 07:58:47
falls es doch irgendwo Openview-Interessierte gibt: Im dortigen Forum steht man vor den gleichen Problemen wie ich...

http://forums1.itrc.hp.com/service/forums/questionanswer.do?threadId=1022842


Titel: Re: Error cleaning up agent threads und WeakReference...
Beitrag von: flaite am 03.05.06 - 14:30:05
find ich krass.