LNP242 Make §§§ fast (Logbuch:Netzpolitik)
Das Logbuch Spezial zum besonderen elektronischen Anwaltspostfach Das besondere elektronische Anwaltspostfach soll eigentlich eine elegante Lösung sein, die sichereren E-Mail-Verkehr zwischen deutschen Anwälten und deutschen Gerichten realisieren kann. Nach einer... Das Logbuch Spezial zum besond...

Hier folgen meine Gedanken zu den Problemen bei der Umsetzung des „elektronischen Anwaltpostfachs“, wie sie im „Logbuch Netzpolikt 242“ (Podcast) dargestellt werden. Ich habe sie dort auch als Kommentar veröffentlicht.

Hier nur noch kurz der Kontext: was ist das „beA“: „Das besondere elektronische Anwaltspostfach (beA) ermöglicht Rechtsanwälten die sichere elektronische Kommunikation mit der Justiz und untereinander. Jeder in Deutschland zugelassene Rechtsanwalt verfügt über ein solches elektronisches Postfach.“ Markus Drenger (CCC) hat mehrere Sicherheitslücken in der Implementierung gefunden (Talk).

Hier nun mein Kommentar.

In meiner Wahrnehmung werden mittlerweile überwiegend Webanwendungen entwickelt. Ich weiß nicht, wie es konkret bei Atos aussieht, aber das Wissen um das Bauen von nativen Anwendungen scheint mir mittlerweile nicht mehr so weit gestreut zu sein wie bei Webanwendungen. Letztere haben ja auch unbestrittene Vorteile: eine zentrale Installation auf einer bekannten Umgebung statt vieler dezentraler Installationen auf unbekannten Umgebungen. Ein Patch ist da eingespielt oder nicht eingespielt, bei nativen Anwendungen gibt es immer was dazwischen.

Beim beA ist jedoch eine lokale Installation notwendig, um auf die Smartcard zugreifen zu können. Also wird ein Server installiert, um mit der Smartcard zu kommunizieren, und auf eher abenteuerliche Weise mit einem Zertifikat ausgestattet. Wie machen denn das andere Lösungen? Die z.B. mit dem ePerso kommunizieren? Nun hat man sich dann doch eine lokale Installation ins Boot geholt und muss gleichzeitig Kopfstände machen, um damit zu kommunzieren. Ein lokaler Server … da merkt doch der Nutzer viel weniger, wenn da was schief läuft, der z.B. nicht startet. Ich stimme zu, dass hier eine lokale Anwendung passender wäre. Die Unterstützung von mindestens Windows und MacOS, mglw. auch Linux, in diversen Versionen ist jedoch sicherlich nicht einfach.

Die Sache mit den Terminalservern scheint mir ja die Vorteile der Smartcards zu nichte zu machen. Wie oft werden die eingesetzt? War das der BRAK vor Beginn des Projektes bekannt?

Die „Vertretungsregel“ begründet die Einführung des HSM, das die „Umschlüsselung“ durchführt. Damit ist die Ende-zu-Ende-Verschlüsselung kaputt. Fachlich finde ich die Anforderung nachvollziehbar. Muss denn wirklich der Rechtsanwalt persönlich adressiert werden, oder reicht es, seine Kanzlei zu adressieren? Bei den Gerichten wird man doch wohl auch nicht einzelne Personen adressieren, oder? Wenn man eine ganze Kanzlei oder Teile davon adressieren kann und die betreffenden Mitarbeiter Zugriff auf das Postfach haben, bräuchte niemand umschlüsseln. Dito bei den Absendern.

Dann könnte man auch fast schon De-Mail einsetzen. Aber halt, die Kommunikation erfolgt über OSCI. Das ist aber nur ein Transport-Protokoll. Ist die Payload weiter strukturiert? Wird z.B. ein Aktenzeichen angegeben, damit die Nachricht im Gericht gleich einer elektronischen Akte zugeordnet werden kann? Das geht dann auch in die Richtung „wir bräuchten einfach mal eine Open-Source-Komponente, die E2E-Verschlüsselung zwischen Alice und Bob ermöglicht“ – was wird genau ausgetauscht?

Das habe ich auch nicht verstanden: man kann sich als einfacher Bürger anmelden, wie kann man dann kommunizieren? Braucht man dann auch beA?

Zu guter Letzt: PDF. Ja, PDF ist nicht sicher. Ich vermisse jedoch einen Gegenvorschlag. Nur Text und JPG/PNG? Unrealistisch. Statt PDF ginge PDF/A, aber wer erklärt allen RechtsanwältInnen, dass statt PDF PDF/A zu erzeugen ist und wie man das im Programm der Wahl macht? Habe ich übrigens auch schon gehen: eingehende PDFs mittels Ghostscript in PDF/A wandeln wg. IT-Sicherheit.

Über das beA ließe sich also mindestens nochmal 2 Stunden diskutieren.

In Who do you want to KISS? – About simplicity in coding Ralf Westphal reflects on what simplicity means in programming:

Who do you want to KISS? – About simplicity in coding

He observes that simplicity is relative, esp. relative to the „scarcest resource“. For Ralf „in the long run the scarcest resource therefore is reading or modification time„. In TDD there is a step when you can create simplicity in respect to reading/modification time:

It means, you need to find time to optimize for reading/modification later. Interestingly TDD has this time built in. That’s what the refactoring phase is for. During refactoring you apply the KISS principle once more – now creating simplicity for reading/modification time. If thereby the simplicity for coding time is destroyed so be it.

And even then, simplicity regarding code reading and modification is in the eye of the beholder. Some programmers like high level abstractions like higher order functions while other like a more verbose but easier to follow procedural style. This is often related to the level of experience:

A simple solution for one person can be a complicated solution for another person. Sad, but true. The only way out of this is to keep all team members close together in their competencies (as long as there is a chance one member needs to deal with another’s simple solutions).

Unter dem Titel „Why Coffee is good for Developers“ hielt Moritz Grauel einen Talk über CoffeeScript. Er brachte den Vortrag locker bis lustig rüber und scheint beispielsweise ein Fan von oatmeal.com zu sein.

CoffeeScript will „Javascript minus (einigen) WTFs“ sein, von denen Moritz einige präsentierte (via wtfjs.com). Genannt wurde z.B.

  • Operator „==“ mit type coercion, „===“ ohne (anscheinend haben sich bei der EcmaStandardisierung die Microsoft Jungs (und Mädels) gegen die Netscape Jungs (und Mädels) durchgesetzt)
  • Zahlen sind generell floats (einfache Genauigkeit)
  • automatische Typkonvertierung insbesondere Strings und Zahlen sind nicht immer Sinnvoll
  • der inkonsequente Array-Konstruktor (new Array(5) erstellt ein 5-elementiges Array, new Array(4,5) erstellt ein Array [4,5]), ich würde für gleichzeitige Deklaration

Als Metapher sehr schön ein Foto mit den Büchern „Javascript Definitive Guide“ und „Javascript the good parts“ nebeneinander – ersteres 5x so dick wie zweiteres.

Allerdings würde ich sagen, was auf der Folie for „Javascript sucks“ stand: learn your tools. Nur weil Javascript im Namen „java“ hat und die Syntax wie Java/C/C# you-name-it aussieht, ist sie doch vom Konzept her um einiges entfernt. Siehe auch JavaScriptRocks . Bei dieser Gelegenheit kann ich auch die Hintergrundartikel zum Thema „Closures in Javascript“ empfehlen, weil er auf das Innenleben von JS eingeht.

Wie auch immer, Moritz kündigt Coffeescript als „Javascript without the fail“ an. Coffeescript kompiliert zu lesbarem Javascript (es gibt also eine einfache Exit-Strategie, falls man Coffeescript wieder loswerden will: einfach javascript generieren und damit weiterarbeiten). Der Nachteil ist dabei, dass Debuging etc. nur anhand des generierten JS Codes geht.

Die CS Syntax hat significant whitespace, d.h. geschweifte Klammern und Semikolons fallen weg, runde Klammern bei Funktionsaufrufen sind optional, das function keyword wird durch „->“ ersetzt. Ein schöner Vergleich einer jquery-Konstruktes in JS und in CoffeeScript. Ich finde es zumindest gewöhnungsbedürftig, insbesondere wenn die runden Klammern bei Funktionsaufruf wegfallen, dann aber die Argumente der anonymen Funktion in Klammern stehen.

Für weitere Features siehe Vortrag. Bei meiner Recherche ist mir aufgefallen, dass es seit Javascript 1.7 auch list comprehension für Arrays gibt, lt. Wikipedia dies aber nur durch Mozilla unterstützt wird.

Insgesamt schreibe ich wahrscheinlich (noch) nicht genug JS, um von CS zu profitieren.

Interessant fand ich, dass Moritz weder PPT noch Keynote sondern ein HTML/CSS/JS basiertes Präsentationsprogramm namens impress.js benutzt, bzw. seines eigenen CS port. Er hat dazu ein paar Anmerkungen gemacht. Die Animationen fand ich beeindruckend. In der Präsentation sah das flüssig aus. Auf meinem Rechner ruckelt es allerdings. Er gab gleich den Hinweis, dass die Präsentation vollständig nur mit einem aktuellen Webkit-Browser funktioniert, aber auch mit anderen Browser anzusehen sei. Bei Chrome 17 meinte die Präsi, dass nicht alle Funktionen unterstützt werden, nach Upgrade auf Chrome 18 kam die Meldung nicht.

Alles in allem ein interessanter Vortrag.

Update: Moritz verweist auf/empfiehlt einen Google Tech Talk Javascript: The Good Parts von Douglas Crockford.

Glenn Vanderburg hielt auf der „Lone Star Ruby Conference 2010“ einen interessanten Vortrag mit dem Titel „Real Software Engineering“. Er bezeichnete dabei heutiges „Software Engineering“ (dt.  „Software-Technik„) als Karikatur einer Ingenieursdisziplin  und versuchte, über „Real Engineering“ (also traditionelles Ingenieurswesen) zum „Real Software Engineering“ zu gelangen.

Inhalt

Zunächst unternahm Vanderburg ein kurzen Ausflug in die Geschichte der Software-Technik:

  • die erste Konferenz zum Thema,
  • dem in seiner Auswirkung desaströsen Paper zum Wasserfallmodell – als Negativbeispiel für Informationsdarstellung -,
  • dem nachfolgenden Versuch, ein definiertes Prozess-Steuerungsmodell zu definieren
  • der Annahme, das Ingenieure als Arbeitsergebnisse Dokumente haben (daher dokumentenlastige Vorgehensmodelle)

In anderen Ingenieursdisziplinen gehe der Fortschritt meist von Praktikern aus. (Mathematische) Modelle würden als Kosteneinsparung genutzt, um weniger physische Modelle zu bauen. Die physischen Modelle werden genutzt, um die mathematischen Modelle zu überprüfen.

In der Software-Technik würden Modelle (im Sinne von physisch) und Tests wenig kosten, daher könne man sich die Nutzung von mathematischen Modellen (à  la UML etc.) im Vergleich zu anderen Ingenieursdisziplinen verringern. Mehr noch, Code sei letztlich das Modell und Compiler/Linker/etc. seien in der Analogie zur Baustelle die Arbeiter. Dies sei heute um eher einsehbar, da heute Code mehr denn je so einfach zu lesen wie zu schreiben ist.

Schließlich stellte Vanderburg agile Vorgehensweisen als „empirisches Prozess-Steuerungsmodell“ vor. Derartige Modelle würden auch in anderen Ingenieursdisplinen genutzt.

In Anlehnung einer Definition für das Bauingenieurswesen schlägt er folgende Definition für Software-Technik vor:

… ist die Wissenschaft und Kunst, System ökonomisch und elegant so zu entwerfen und zu erstellen, dass sie sich leicht den Situationen anpassen, denen sie ausgesetzt sind.

Hier kämen die Spannungsfelder Wissenschaft (Mathematik) – Kunst – Ökonomie gut zum Ausdruck.

Highlights

Toll fand ich die Darstellung, wie das Waterfall-Paper missverstanden werden konnte.

Interessant auch die Feststellung, dass die der Fehlerkostenkurve von Boehm zugrundeliegende Projekte nach dem Wasserfall-Modell waren und die Kurve daher in Wahrheit die Kosten von großen Rückkoppelungsschleifen darstellt.

Gespräch mit Kollege:
Gegeben Klasse A und Klasse B extends A und ich rufe im Konstruktor von A eine Methode auf, die in B überschrieben wird und die dort auf eine in B definierte Variable zugreift, dann ist diese Variable zum Zeitpunkt des Aufrufs nicht initialisiert. Das stimmt.

Wozu brauchst Du das?
Klasse Gruppenbaum, im Konstruktor lese ich Baum aus DB.
Na das ist ja nicht so gut. Konstruktoren sollten ihr Objekt in einen definierten Zustand bringen, mehr aber auch nicht. Wurde schon vor langer Zeit beschrieben.

Letztens haben wir nach Hardware- und JDBC-Treiber-Wechsel folgende Fehlermeldung bekommen:

ORA-01000: too many open cursors (oder auf deutsch: maximale anzahl offener cursor überschritten)

Tatsächlich gab es noch 2 Statements im Application-Server, bei das Statement nicht geschlossen wurde. Man findet die betreffenden Statements mit folgendem SQL:

  1. select
  2.         c.sid,
  3.         c.address,
  4.         c.hash_value,
  5.         COUNT(*)       as "Cursor Copies"
  6. from    v$open_cursor c
  7. group by
  8.         c.sid,
  9.         c.address,
  10.         c.hash_value
  11. having
  12.         count(*) > 2
  13. order by
  14.         3 desc

Unter Umständen kann man im Live-System beobachten, wie die Anzahl der offenen Cursor wächst.

Offensichtlich hat uns der vorherige JDBC-Treiber das nicht-Schliessen des Statements vergeben.

Laut Java-Spezifikation werden Finalizer in Java aufgerufen, bevor das entsprechende Objekt durch den Garbage Collector aus dem Speicher entfernt wird. Das klingt erst mal verlockend – hier könnte man ja automatische das Freigeben von Resourcen unterbringen.

Aber! Es wird nicht garantiert, wann der Finalizer aufgerufen wird. Die freizugebenden Resourcen sind solange blockiert. Schlimmer kommt es noch, wenn ein Finalizer ungewöhnlich lange für die Verarbeitung benötigt. Dann können die Resourcen, die die Objekte der anderen anstehenden Finalizer halten, nicht freigegeben werden. Dies kann zu Out-of-Filehandles oder zu Out-of-Memory-Fehlern führen, wenn die Entwickler sich auf die zeitnahe Abarbeitung von Finalizern verlassen.

Dies ist uns letztens passiert: Unsere Anwendung beendet sich nachweisbar nach einigen hundert Webservice-Aufrufen. Ergebnis der Problemanalyse: Ein Objekt einer Klasse des Oracle IAS scheint den Finalizer-Warteschlange zu blockieren, somit werden Objekte aus dem AXIS-(1.0)-Framework nicht finalisiert, die jedoch Referenzen auf speicherfressende DOM-Objektbäume halten. Diese DOM-Objektbäume können dadurch nicht garbage-collected werden, sammeln sich an und schliesslich kommt der Out-of-Memory-Fehler. Im generierten Webservice-Stub-Code haben wir manuell den Aufruf an den Finalizer (genauer: an die dispose-Methode) eingefügt und siehe da, dass Problem ist beseitigt.

An einer anderen Stelle (ebenfalls AXIS) sind wir vor 1-2 Jahren in ein ähnliches Problem gelaufen, da ging es jedoch um FileHandles oder Netzwerk-Ports. Auch da half manuelles freigeben der Resourcen.

Fazit: Es ist besser, die Resourcen von Hand freizugeben. „Zur Sicherheit“ mag man noch einen Finalizer schreiben, aber wenn dieser wiederum die Finalize-Warteschlange blockieren könnte (etwa weil auf ein Netzwerk-Timeout gewartet wird), dann sollte man auch davon die Finger lassen.

Tools zum Analysieren von Memory-Dumps:

Wir hatten folgendes Problem.

Symptom: Manchmal wurden Bilder nicht geladen, Manchmal gab es Fehlermeldungen am Anfang oder Ende einer Seite.

Umgebung: J2EE-Anwendung auf Oracle IAS 9.0.4 (2 OC4J-instanzen) unter Sun Java VM 1.4.2 auf HP-UX, 8 Prozessor-Maschine, als Entwicklungsumgebung.

Analyse:

  1. vmstat sagt: ca. 35-40 Prozesse laufen ständig, Anteil user 15%, Anteil sys 85%, idle 0%. Memory ist nicht knapp, Paging kaum
  2. top sagt: eine oc4j-Instanz verursacht die prozessorlast
  3. die log-files sind leer! (0 bytes)
  4. jvm-stacktrace ergibt keine weiteren auffälligkeiten (kein anwendungscode im stacktrace, mostly waits oder Input/outputs)

Wir spielen das vorletzte build ein, welches am tag zuvor noch gelaufen ist.

Analyse:

  1. redeploy sehr langsam
  2. symptom und analyseergebnisse bleiben gleich

Wir rufen beim betrieb an.

Ergebnis: Filesystem voll!

nachdem der betrieb das problem behoben hatte, lief die anwendung (nach dem redeploy der aktuellen version) wieder normal.