Re: [Hbci4java-help] [Bug 84] Probleme, wenn Threads nicht selbst erzeugt werden (bei Tomcat etc .)
Brought to you by:
kleiner77
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-02-17 23:02:17
|
Hi, > > ich antworte mal direkt per Mail, denn 'ne Diskussion im Bugzilla > > halte ich nicht für soo sinnvoll :) > > Das ist Ansichtssache, im Bugtracker könnten evtl. auch andere > mitdiskutieren, wie in einem Diskussionsforum. Fänd ich gar nicht so > blöd. > Aber ich bin da ganz flexibel :) Wenn überhaupt dann Mailing-Liste. Diskussionen im BugTracker werden die wenigsten überhaupt wahrnehmen, wenn ein bestimmter Bug sie nicht selbst betrifft :) Ich starte mal ein CC an die Liste, die Diskussion begann bei diesem Bug: https://bugzilla.kapott.org/show_bug.cgi?id=84 > Ansonsten muss ich gestehen, dass mir noch gar nicht in den Sinn > gekommen ist, dass ein Anwendungsprogramm die Möglichkeit hat/haben > könnte, eine eigene HBCIPassportFactory oder einen eigenen > HBCIPassport zu implementieren. Mir ist derzeit auch nicht klar, warum > bzw. wann das nötig sein sollte, aber vielleicht gibt es derartige > Situationen. Diese Erweiterbarkeit ist eines der am häufigsten verwendeten "Special-Features" von HBCI4Java. Z.B: Die Bibliothek wird sehr oft in serverseitigen Anwendungen ein- gesetzt. Dort wird es z.B. gewünscht, dass bei der (on-the-fly-) Erzeugung von Passports diese Daten nicht in einer Datei gespeichert werden, sondern entweder gar nicht, oder in einer DB, oder über ein Netzwerk-Protokoll in einem remote-Backend abgelegt werden... Außerdem weiß ich von Entwickler-Teams auf Banken-Seite, die ihre eigenen Server-Entwicklungen gegen HBCI4Java testen. Dafür ist es notwendig, eigene Geschäftsvorfälle in die Client-Bibliothek einzubringen, die entweder so (noch) gar nicht im Standard spezifiziert sind und/oder noch nicht in HBCI4Java enthalten sind. Auch gibt es wohl einige Rewriter-Module, die für bestimmte Anwendungs- fälle entwickelt wurden (die aufgrund ihrer sehr speziellen Use-Cases aber nicht den Weg in die offizielle HBCI4Java-Suite gefunden haben). Für eine bankinterne-Anwendung wurde eine spezielle Beschreibung der HBCI-Version 2.2 benötigt (die Bank hatte u.a. intern einige Segmente auf andere Versionen umgestellt). Ein enstprechendes HBCI4Java-basiertes Client-Test-Tool war sehr einfach zu realisieren, indem einfach eine entsprechend modifiziere XML-Datei mit der angepassten Syntax- Beschreibung in den Java-CLASSPATH gelegt wurde und als HBCI-Version nicht "220", sondern "220-modified" verwendet wurde... Mit etwas Fleiß könnte ich eine ganze Menge derartiger Beispiele aufzählen, was der Grund dafür ist, dass ich bestimmte Features von HBCI4Java auch weiterhin nicht fest in der Lib verdrahten will, sondern über einen Factory- oder Plugin-Mechanismus dynamisch erweiterbar halten will. Ich gebe Dir natürlich insofern Recht, dass solche Sachen wie die HBCI-Datentypen (numerisch, alphanumerisch, binary, ...) nicht über eine von außen erweiterbare Factory instanziiert werden müssen, denn wenn das notwendig wäre, würde man mit eigenen Implementierungen wohl mehr Schaden anrichten als alles andere (im Moment wäre aber sogar das möglich - aber das ist nur ein Nebeneffekt des Software-Designs an dieser Stelle und keine "Absicht"). > Ich hatte mir das ganze bisher eher so vorgestellt, dass alle > Factories, Passports, der Kernel etc. von HBCI4Java bereitgestellt > werden, und vom Anwendungsprogramm nur > konfiguriert/instantiiert/benutzt werden. > Das scheint mir auch ausreichend zu sein, wenn mit den vorhandenen > HBCI4Java-Klassen der HBCI-Standard abgedeckt wird. Falls jemand noch > Lücken entdeckt, also etwas, was HBCI4Java können sollte, aber nicht > kann, wäre es vermutlich besser, um eine Aufnahme des zusätzlichen > Codes in das offizielle HBCI4Java-Repository zu bitten, anstatt im > Anwendungsprogramm Teile der HBCI-Implementierung unterzubringen. Natürlich. Bei den Möglichkeiten zur Erweiterbarkeit ging es primär auch nicht darum, HBCI4Java tatsächlich um HBCI-Funktionalitäten erweitern zu können. Allerdings gebe ich zu, dass ich ursprünglich die Vorstellung hatte, dass ich mit HBCI4Java nur das Framework und einige Basis-GVs liefere und die oft zitierte "Community" z.B. weitere Implementierungen von Geschäftsvorfällen beisteuert. Technisch wäre das bis zu einem gewissen Zeitpunkt möglich gewesen, allerdings hatte wohl gerade niemand Zeit, sich damit zu beschäftigen ;-) Diese "Erweiterungen" sollten auch nicht verstanden werden als "im Anwendungsprogramm Teile der HBCI-Implementierung unterzubringen", sondern vielmehr tatsächlich als "Aufsatz" auf HBCI4Java, der z.B. Unterstützung für weitere Geschäftsvorfälle, alternative Speicher- Medien für Passports (Datenbanken, RPC-Services...) usw. liefern. (Ich vermute, dass z.B. in Hibiscus einige HBCI4Java-Klassen und/oder -Methoden überschrieben wurden, um spezielle Funktionalitäten einzubringen...) > ... > Wenn man diese Kapselung so einhalten würde, bräuchte man -wenn ich > das richtig verstanden habe- gar keine Factory, man könnte Objekte der > einzelnen Klassen einfach normal instantiieren und nutzen. Das hätte aber genau den Nachteil, dass die HBCI4Java-Bibliothek nur die Klassen benutzen kann, von denen sie zur Entwicklungszeit bereits weiß. Sprich: eigene Passport-Speicher-Implementierungen, eigene Hilfsklassen für Geschäftsvorfälle usw. wären nicht mehr möglich. > Ganz grob so in diesem Stil: > [pseudocode] > // Pro Thread, vor der ersten Kommunikation mit der Bank > HBCICore core = new HBCICore(locale, loglevel, shadelevel, callback, > options); > HBCIPassport passport = new HBCIPassport(passporttype, > passportFilename); > HBCIHandler handler = new HBCIHandler(core, passport, hbciVersion); > // core, passport und handler sind jetzt normale Instanzen der > Klassen, die zerstört werden können > > // irgendwann ... (nur für den aktuellen Thread) > handler.close(); > passport.close(); // Passportdatei wird natürlich geschrieben und > geschlossen > core.close(); // Nur die eigene Instanz des Core > core = null; // RAM freischaufeln > passport = null; // RAM freischaufeln > handler = null; // RAM freischaufeln > [/pseudocode] Das Problem dabei sind z.B. Anwendungen, die in einem Application- Server laufen und HBCI-PIN/TAN via iTAN oder einem anderen Zweischritt- Verfahren machen. Denn dabei MUSS der HBCI-Dialog zunächst gestartet werden. WÄHREND der Dialog-Ausführung wird vom HBCI-Server nach einer bestimmten TAN gefragt - diese Frage muss an den Nutzer weitergereicht werden. Dabei entsteht also ein neues Response (mit der Rückfrage nach der richtigen TAN) sowie ein neuer Request (mit dem der Nutzer die TAN liefert). Der neue Request des Nutzers muss die gelieferte TAN natürlich für den "alten" HBCI-Dialog verwenden, so dass man hier eine Kopplung im Sinne von "Sessions" braucht. Und damit wird es schon nicht mehr so einfach wie es in Deinem Pseudocode aussieht ;-) > ... Ich denke aber nicht, dass man Factories pro Thread verwalten > müsste, das dürfte wohl nichts bringen. Das denke ich allerdings auch. Der aktuelle HBCI4Java-3-Code ist auch so ausgelegt, dass Factories tatsächlich "global" sind und nicht pro Thread oder HBCI-Session differenziert werden können. > Falls man wirklich zusätzliche Passports oder dergleichen benötigt, > kann man diese ja beim Programmstart an der Library registrieren. > Danach könnten diese für alle Threads zur Verfügung stehen, die diesen > Typ benötigen. Da ja jeder Passport-Typ einen eindeutigen Namen haben > muss, sind ja Verwechslungen ausgeschlossen. So ist der derzeitige Stand der Dinge. Nur dass keine zusätzlichen Klassen "registriert" werden (in engerem Sinne). Statt dessen hat eine Anwendung einfach die Möglichkeit, die von HBCI4Java verwendete Factory durch eine eigene Factory-Implementierung zu ersetzen (siehe mein vorheriges Mail mit dem Code-Beispiel). > Aber was meiner Meinung nach pro Thread verwaltet werden sollte: > -> Einstellungen, die direkt die Usability betreffen (z. B. die zu > verwendende Sprache/Locale) ACK. > -> Alle Einstellungen zur Kommunikation mit der Bank (BLZ, Host, Port, > Filter, UPD, BPD, unterstützte Securitymechanismen, etc.) Sowieso. Die Verwendung von globalen Variablen zur Konfiguration von Passports war design-technisch ein grober Fehler, an den man sich über die Jahre wohl gewöhnt hat :) > -> Callback-Objekte Hier wäre schon wieder die Frage, ob das tatsächlich notwendig ist. Man könnte einerseits natürlich pro HBCI-Session individuelle Callback-Objekte registrieren. Andererseite könnte man jedem Callback-Aufruf ja auch einfach einen Parameter "HBCISession session" mitgeben, der sämtliche session- relevanten Daten enthält, so dass auch EIN Callback-Objekt in verschiedenen HBCI-Sessions unterschiedlich agieren könnte. Zumindest ist das der gegenwärtige Stand der Entwicklung... > Allgemein gesprochen, halte ich es für "vergebliche Liebesmühe", > HBCI4Java daraufhin zu optimieren, dass man es durch eigenen Code > erweitern kann, der dann von HBCI4Java genutzt wird, dies ist > vermutlich wenig relevant... Siehe Anfang mein Mail - da irrst Du Dich :) > In der Praxis dürfte es viel eher nützlich sein, wenn mehrere > Transaktionen mit mehreren verschiedenen Banken exakt parallel laufen > können, ohne dass die Gefahr besteht, dass diese sich gegenseitig > stören oder beeinflussen. Das ist ebenfalls ein wichtiger Punkt, der in HBCI4Java-2 schon einigermaßen gut unterstützt wurde, allerdings leider erst "nachträglich", was zu diversen Kompromisslösungen geführt hat (Du hast das bereits gut erkannt).. HBCI4Java-3 wird an dieser Stelle wohl etwas sauberer sein... Viele Grüße -stefan- |