Dass die ZIP-Implementierung in java.util.zip nicht mit Umlauten umgehen kann, schrieb ich ja schonmal. In Java 1.7 wird das Problem endlich gefixt sein. Der Bug-Report bei SUN stammt übrigens vom 07. Juni 1999! Hatte also gerade 10. Geburtstag. Weil das einfach nur peinlich ist, nehm ich jetzt jazzlib. Das 60k-Jar-File in den Classpath werfen und die Klassen aus "net.sf.jazzlib" (statt "java.util.zip") verwenden. Fertig. Die API ist identisch zu der von SUN.
Eigentlich wollte ich Jameica und Hibiscus endlich mal ausführlich mit OpenJDK testen. Aber nachdem ich 1 Stunde an mir selbst verzweifelte, fiel mir das hier auf.
Test 1: Debugger läuft bis zum Breakpoint in Zeile 118 durch. Der String "s" hat den Wert "1.7+" (obwohl ich in der Zeile drüber alles ausser Zahlen und Punkt entfernt habe).
Test 2: Zusätzlicher Breakpoint in Zeile 117. In dem warte ich ein paar Sekunden und steppe erst dann weiter. Das "+" ist entfernt worden.
WTF?! Ein und der selbe Code liefert unterschiedliche Ergebnisse, wenn man nur ein paar Sekunden wartet? Kein Wunder, dass der gesuchte Bug nur dann auftrat, wenn ich keinen Breakpoint im verdächtigen Code hatte. Natürlich tritt der Effekt in einer einfachen Testklasse mit main()-Methode nicht auf.
Ich weiss nicht, ob ich weiterhin an mir selbst zweifeln soll oder OpenJDK einfach in die Ecke werfe. Für heute jedenfalls letzteres.
Bei meinem letzten Test musste ich mich ja echt zusammenreißen, keinen Rant zu schreiben. Mit Release 1.5 ist die JCR-Implementierung aber tatsächlich out-of-the-box benutzbar. Einfach jackrabbit-standalone-1.5.0.jar herunterladen. Starten. Fertig. Ein Repository mit dem Namen "default" wird automatisch angelegt und ist via RMI und WebDAV ansprechbar. Geht doch ;)
Seit SUN den Java-Source mehr und mehr freigibt, hat sich mit OpenJDK eine weitere Java-Distribution neben SUN Java entwickelt. Leider gibt es von OpenJDK bisher nur für Ubuntu, Red Hat und Fedora Binär-Pakete, nicht aber für meine SuSE 10.3. Und das Zeug selbst zu kompilieren ist eine Qual. Ich kann derzeit also leider nicht analysieren, warum Hibiscus nicht mit OpenJDK funktioniert. Als Workaround hilft aber weiterhin, die Java-Distribution direkt von SUN zu verwenden.
Merken: Mit jDTAUS existiert neben Obantoo (welcher von Hibiscus genutzt wird) ein weiterer freier DTAUS-Parser. Daher: Wenn ihr mal DTAUS-Dateien lesen müßt - versucht es gar nicht erst sondern nehmt eine der beiden freien Alternativen. Das Format ist wirklich schmerzhaft. Das weiss ich aus eigener Erfahrung ;)
Meine Fresse, das hat mich jetzt einen kompletten Tag gekostet. Jetty kann man ja prima als embedded Servlet-Container verwenden. Selbst so Sachen wie SSL und Authentifizierung kann man da völlig frei sowohl via Config-Dateien als auch mit Programm-Code definieren. In deren Wiki ist z.Bsp. beschrieben, wie man Security-Constraints ohne web.xml programmiert. Das funktioniert auch prima. Allerdings liefern folgende Konstrukte in einer JSP-Seite immer null.
Ist natürlich blöd, wenn die Webanwendung wissen will, wer denn gerade eingeloggt ist.
Hier mal der relevante Code laut Doku:
SecurityHandler sh = new SecurityHandler();
sh.setUserRealm(...);
sh.setConstraintMappings(...);
WebAppContext webappcontext = new WebAppContext("/pfad/im/dateisystem","/contextpfad");
webappcontext.addHandler(sh);
server.setHandler(webappcontext);
Damit geht zwar prinzipiell das Login. Allerdings kennt der Request den Usernamen nicht. Grund für das Dilemma: WebAppContext erstellt bereits intern im Konstruktor einen eigenen SecurityHandler. Mit oben genanntem Beispiel-Code besitzt der WebAppContext zwei SecurityHandler - einen internen (und unkonfigurierten) sowie den explizit angegebenen. Bei der Verarbeitung eines HTTP-Requests kommen dann vermutlich beide zum Zug. Der erste autorisiert den User, der zweite plättet ihn wieder.
Daher hier die funktionierende Variante: trommelwirbel
WebAppContext webappcontext = new WebAppContext("/pfad/im/dateisystem","/contextpfad");
SecurityHandler sh = webappcontext.getSecurityHandler(); // die entscheidende Zeile
sh.setUserRealm(...);
sh.setConstraintMappings(...);
server.setHandler(webappcontext);
Woaah, da hat sich tatsächlich jemand die beiden gruseligsten Protokolle genommen und eine Java-Implementierung geschrieben. Das Ding heisst JLAN und ist jetzt unter der GPL verfügbar. Mir schwirren schon wieder 1000 Ideen durch den Kopf, was man damit anstellen könnte ;)
Ich hasse ja die Webseiten von SUN. Will man dort Java herunterladen, darf man sich erst durch 15 unübersichtliche Seiten wühlen, wird anschließend 8 mal redirected, muss den Lizenzbestimmungen zustimmen und erhält dann eine mit Session-IDs gepflasterte URL. Für automatische Downloads via wget also völlig ungeeignet.
Muss ich mir bei Gelegenheit mal noch genauer anschauen:
SWTJasperViewer: Viewer für Jasper-Reports, der nicht nur Standalone gestartet sondern auch einfach auf ein SWT-Composite/Canvas gepappt werden kann. Ein idealer Kandidat also, um komplexe tabellarische und grafische Auswertungen direkt in einem Jameica-Plugin anzeigen zu können. Jetzt muss ich nur noch wissen, was man denn mal reporten könnte ;)
airTODO: Ein kleines Projektmanagement- und Zeiterfassungstool, welches als Plugin direkt in Eclipse laufen kann. Sowohl im Standalone- als auch im Client-/Server-Betrieb. Erfordert jedoch Java 6.
OpenBravo: In Java geschriebene ERP-Software, für die es eine deutsche Lokalisierung und sogar einen SKR03-Kontenrahmen gibt. Als Servlet-Container kommt Tomcat zum Einsatz. Sieht mächtig WebZwoNull-mäßig aus, läuft jedoch nur mit PostGreSQL oder Oracle als Datenbank.
Vor einiger Zeit hatte ich schonmal von Apache Directory gelesen - es war damals aber noch nicht so richtig brauchbar. Das hat sich inzwischen wohl geändert. Mit Apache Directory Server existiert nun eine in 100% Java geschriebene LDAPv3-Implementierung. Und als Sahnehäubchen gibts eine auf Eclipse-RCP basierende IDE namens Apache Directory Studio zur Administration und Verwaltung (die übrigens auch mit OpenLDAP funktioniert). Den Server selbst hab ich mir noch nicht angeschaut, die IDE hingegen macht einen durchaus guten Eindruck. Merken!
Seit dem Update auf Version 3.2 legte Eclipse beim CVS-Update immer nervige Gedenkpausen ein, die es mit dem Statustext "Receiving file: Template" füllte. Ich hab jetzt mal etwas recherchiert und die Ursache gefunden. In dieser Eclipse-Version wurde das Konzept einer "Model-basierten" CVS-Synchronisierung eingeführt, die es anderen Komponenten der IDE erlaubt, die Synchronize-View ebenfalls zu nutzen. Siehe Eclipse CVS-FAQ. Wie bereits dort erwähnt, scheint die Sache noch nicht richtig getestet zu sein, was wiederrum zu o.g. Performance-Problemen führte. Mit #152581 existiert hierzu auch ein Bug-Report.
Unterdessen kann man sich mit der Abschaltung dieser Funktion behelfen: "Windows»Preferences...»Team»CVS»Synchronize/Compare" öffnen und dort die Option "Allow models (e.g. Java) to participate in Synchronizations" deaktivieren.
Tipp: "Control#getLocation()" liefert ja leider keine absolute Position (also in Bezug auf das Display) sondern nur eine relative Position zum Parent. Hiermit kann man jedoch auch die absolute Position ermitteln:
Text text = new Text(parent,SWT.BORDER);
// Liefert nur die relative Position
Point relativ = text.getLocation();
// Liefert die absolute Position
Point absolut = text.toDisplay(text.getLocation());
Damit kann man zum Beispiel ein Popup-Menu korrekt positionieren.
Bisher erzeugte ich Rechnungen im XML-Format, die mittels XSLT in HTML umgewandelt wurden. Da mir das Druckbild direkt aus dem Browser heraus aber nicht gefiel, hab ich das Monster-Pamphlet zu XSL-FO durchgearbeitet und Apache-FOP integriert, damit hinten PDF-Dateien rausfallen. Und was finde ich heute: xhtmlrenderer: Eine Java-Bibliothek, die PDF direkt aus xHTML erstellt. War ja wieder mal klar. Damit kann ich die Rechnung viel bequemer mit CSS layouten, statt mich mit XSL-FO quälen zu müssen.