ZIP-Dateien mit Umlauten entpacken

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.

Race-Condition im Regex-Parser von OpenJDK?

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.

"lastIndexOf" in JSTL

"fn:lastIndexOf" gibts leider nicht. Workaround:
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<c:set var="text" value="${fn:split('de.foo.bar.Dings','.')}" />
${text[fn:length(text)-1]}

Ausgabe:
Dings

Hibiscus und OpenJDK

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.

jDTAUS: Parser für Java

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 ;)

request.getRemoteUser() in Jetty

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.
request.getUserPrincipal();
request.getRemoteUser();
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);

Schnelldownload für Java

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.

Gerade im Quickstart-Guide von airTODO entdeckt: http://www.java.com/de/download/manual.jsp - ein Klick. Geht doch.

PS: Achtung - das ist nur das JRE. Reicht also zum Ausführen von Java-Anwendungen, nicht aber zum Selberbauen.

Aktuelle Testliste

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.

Es muss nicht immer OpenLDAP sein

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!

Eclipse: CVS-Update beschleunigen

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.

SWT: Absolute Position eines Controls ermitteln

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.

xhtmlrenderer: PDFs aus xHTML erstellen

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.