Dienstag, 28. Dezember 2010

Hashtable schneller als HashMap





Donnerstag, 23. Dezember 2010

Browsertracking

Es gibt ja ganz unterschiedliche Trackingmethoden. Cookies, Flash, Javascript und Silverlight sind aber nicht die Einzigen Verräter an Bord. Der Browser selbst gibt freiwillig bereits einen ganzen Haufen an Informationen Preis, die mitunter für eine Identifikation ausreichen können. Welche das alles sind und wie eindeutig identifizierbar der Browser ist, lässt sich bei Panopticlick testen.

Link: Panopticlick

42 für Softwarearchitekten

Es gibt wieder einen Vortrag vom Jax TV. Dieses Mal geht es um Architektur- und Designdokumentation. Bestimmt schaffe ich es in den Feiertagen, mir die Zeit zum Gucken zu nehmen.

42 für Softwarearchitekten from JAX TV on Vimeo.

Dienstag, 21. Dezember 2010

Anwendungseigenschaften speichern

Eigentlich gibt es ja kaum eine Anwendung, bei der man nicht ein paar Einstellungs- oder Konfigurationsmöglichkeiten haben möchte. Die Out-of-the-Box-Lösung unter Java ist hier die java.util.Properties Klasse, mit der Eigenschaften gelesen und geschrieben werden können. Aussehen könnte das ganze wie folgt:

    /**
     * Lese properties file.
     */
    public void readProperties() {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("filename.properties"));
        } catch (IOException e) { 
            e.printStackTrace();
        }
    }

    /**
     * Schreibe properties file.
     */
    public void writeProperties(Properties properties) {
        try {
            properties.store(new FileOutputStream("filename.properties"), null);
        } catch (IOException e) { 
            e.printStackTrace(); 
        }
    }

Der Zugriff erfolgt dann, gleich einer HashMap, via props.getProperty("key"). Das ist alles sehr einfach und reicht oftmals aus, um ein paar Werte zur Laufzeit wegzuschreiben. Will man aber Arrays, Objekte oder ganze Wertebeziehungen speichern, muss man diese zunächst in einen String codieren bzw. beim Lesen wieder decodieren. Ist man im Begriff mit so etwas zu beginnen, empfiehlt es sich gleich etwas anderes zu verwenden, weil hier die Rattenschwanzgefahr recht groß ist und letztendlich nur vom Projektziel ablenkt. Gesehen habe ich das allerdings schon mehrfach. Dabei bringt Java für anspruchsvollere Anwendungseigenschaften noch etwas anderes, besseres mit.

Im Package java.util.prefs gibt es die Klasse Preferences, die eine hierarchische Werte- und Objektablage bietet. So ist mittels Preferences.userRoot() eine Rootknoten erhältlich, in den wir bereits verschiedene Objekte ablegen können. Besser ist es aber, einen eigenen Knoten für die Anwendung bereitzustellen, um nicht mit anderen Anwendungen zu kollidieren. Preferences werden nämlich im Benutzerverzeichnis für alle Anwendungen unter .userPrefs/prefs.xml abgelegt. Via Preferences.systemRoot() lassen sich auch systemweite Einstellungen speichern. Um die Anwendungseinstellungen zu laden empfiehlt es sich, einen Unterknoten zu verwenden, der wie folgt erzeugt/geladen werden kann: Preferences.userRoot().node("TestApp"). Dieser Knoten kann nun als Basis für weitere Unterknoten oder für die Werteablage dienen. Um das Laden und Speichern müssen wir uns bequemer Weise nicht kümmern. Unser Knoten befindet sich nach dem Neustarten der Anwendung im gleichen Zustand. Der Zugriff auf die Knoteneigenschaften erfolgt mittels put- und get-Methoden.

java.util.prefs.Preferences appNode = Preferences.userRoot().node("TestApp");
appNode.putInt("fontsize", 10); //Eigenschaft setzen
int fontsize = appNode.getInt("fontsize", 10); //Eigenschaft lesen

Das ganze kann noch weiter getrieben werden, so dass zum Beispiel für jedes Paket ein neuer Knoten verwendet wird.

Preferences packageNode = appNode.node(Test.class.getName())

Bis jetzt lassen sich aber nur die gängigen Wrapper-Klassen sowie Strings und Bytearrays ablegen. Um (fast) beliebige Objekte abzulegen, lässt sich die Serialisierbarkeit von Objektinstanzen nutzen. Die zugrundeliegende Klasse muss also das Serializable-Interface implementieren. Die der Klasse zugrunde liegenden Objektinstanzen können anschließend in ein Bytearray umgewandelt werden, das wiederum mit der Methode putByteArray in den Preferences-Knoten gespeichert werden kann.

   /**
     * Objektinstanzen serialisieren.
     */
    static private byte[] object2Bytes(Object o) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(o);
        return baos.toByteArray();
    }

Der Rückweg, aus dem Bytearray eine Objektinstanz zu erzeugen, ist ebenso einfach.

   /**
     * Serialisierte Objektinstanz wiederherstellen
     */
    static private Object bytes2Object(byte raw[]) throws IOException,
            ClassNotFoundException {
        ByteArrayInputStream bais = new ByteArrayInputStream(raw);
        ObjectInputStream ois = new ObjectInputStream(bais);
        Object o = ois.readObject();
        return o;
    }

Bei der Objektserialisierung ist immer darauf zu achten, dass die Member-Variablen der zugrundeliegenden Klasse wiederum serialisierbare Klassen referenzieren. Andernfalls sind die Member-Variablen mit transient zu kennzeichnen. Das Gilt zum Beispiel für Streams, die nicht einfach serialisiert werden können. Bei der Wiederherstellung enthalten diese Member-Variablen den Wert null.

Die Datenablage erfolgt - wie nicht anders zu erwarten - im XML-Format. Das Endergebnis  können wir uns auch ausgeben lassen.

public static void printPreferences(Preferences prefs) throws IOException,
            BackingStoreException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        prefs.exportNode(byteArrayOutputStream);
        System.out.println(new String(byteArrayOutputStream.toByteArray()));
    }

Und die Ausgabe.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">
<preferences EXTERNAL_XML_VERSION="1.0">
  <root type="user">
    <map/>
    <node name="TestApp">
      <map>
        <entry key="fontsize" value="10"/>
      </map>
    </node>
  </root>
</preferences> 
 
Links: IBM Developerworks 

Montag, 20. Dezember 2010

Crashkurs Testgetriebene Softwareentwicklung

Testgetriebene Softwareentwicklung ist eigentlich eine tolle Sache, die jeder mal probiert haben sollte. Nicht etwa, weil es die beste Methode wäre, Software zu entwickeln. Es ist viel mehr so, dass häufig viel zu wenig Tests geschrieben werden und nicht selten auch die Einsicht fehlt, warum Tests geschrieben werden sollen. Manchmal ist es auch nur die Faulheit, die davon abhält, ein paar mehr Tests zu schreiben. Einmal testgetrieben zu entwickeln, verschafft die Erfahrung, dass die Qualität der Software signifikant steigt, wenn gute Tests erstellt wurden. Die Erfahrung, was gute Tests sind und worauf es ankommt, bekommt man gleich mit oben drauf.

Sehr gut funktioniert das übrigens in der Java-Welt, wenn man auch gleich bei der Entwicklung darauf abzielt, entkoppelten Code zu schreiben. Spring ist da ziemlich hilfreich.

Zurück zur testgetriebenen Entwicklung. Ein großes Haken ist natürlich, dass testgetriebene Entwicklung zu Beginn des Projektes mehr Zeit benötigt. Außerdem ist es unter Entwicklern meist unbeliebt, Testcode zu schreiben. Dem lässt sich allerdings entgegen wirken, wenn man Teams zu zwei Personen bildet, bei der gemeinsam die Spezifikation ausgearbeitet wird und abwechselnd der eine die Implementierung und der andere die Tests schreibt. Nach einiger Zeit erhält man dann ein Projekt, das eine gute Testabdeckung bietet und wenig fehleranfällig auf Änderungen reagiert.

Tests gleich zu schreiben ist auch deshalb gut, weil ein Test, der nicht unmittelbar nach oder eben vor der Implementierung geschrieben wurde, oft nie geschrieben wird. Zumindest so lange nicht, bis genau dort ein Fehler auftritt.









via krsteski.de

Samstag, 18. Dezember 2010

Mein neues Spielzueg, ein Pocketbook 902

Mein neues Spielzeug ist da. Ein Pocketbook 902 Pro. Bisher waren mir die E-Reader immer zu klein, aber der Trend geht ja zu immer größerem. Das Kindle DX kam für mich nicht in Frage. Zum einen wegen fehlender epub-Unterstützung, zum anderen aus ideellen Gründen. Die Pocketbook-Plattform ist offen und es gibt sogar ein Entwickler-Kit, um eigene Anwendungen auf das Gerät zu bringen.

Als tückisch erweist sich jedoch die MicroSD-Card. Die kann man an der Geräteunterseite hineinschieben, was ich auch tat. Die Karte rastete mit einem Klicken ein, nur tat sich nichts. Tatsächlich muss man die Karte mit leichter Gewalt noch viel weiter hineindrücken, als es mit den bloßen Fingern möglich ist. Das habe ich aber auch erst zwei Speicherkarten später rausgefunden. Frauen, mit langen Fingernägeln, haben hier sicher einen grundlegenden Vorteil.

Inzwischen habe ich mein erstes Buch auf dem Pocketbook fast fertig gelesen. Das elektronische Lesen hat Vor- und Nachteile. Das Gerät lässt sich angenehm halten und an das Blättern per Taster hat man sich schnell gewöhnt. Das E-Ink-Display ist zwar entspiegelt, dennoch reflektiert es leicht, was besonders bei ungleichmäßiger oder geringer Raumausleuchtung stört. Der Kontrast ist nicht ganz so stark, wie bei einem gedruckten Buch, dennoch kann man gut auf dem Display lesen. Ich werde es jedenfalls weiter ausprobieren.

*Update 19.12.10*
Leider sind das Boot- und das Off-image, eher hässlich und nichtssagend. Kein Vergleich zu der stylischen Verpackung. Im Forum von The Electronic Book gibt es eine menge Ersatz, der gut für die E-Paper-Displays geeignet ist.

Visuelles Multiplizieren

Eine interessant ausgestaltete Variante der Multiplikation, auch wenn die Ausgestaltung des Rechenweges wohl etwas eigenwillig ist. Die Darstellungsweise ist nicht taufrisch, aber ich kannte sie bisher noch nicht.

How do japanese multiply??

Worauf es bei Passwörtern im Web ankommt *Update*

Es kommt nicht auf die Länge an. Wenigstens nicht bei Passwörten im Web. Unter Entwicklern herrscht nicht selten die Meinung vor, starke Passwörter würden die Sicherheit erhöhen. Der Zwang zur Auswahl komplexer Passwörter ist eigentlich nur ein Delegieren der Sicherheitsanforderungen an den Benutzer. Weshalb das nicht funktioniert, ist mit einem Blick auf die möglichen Wege eines Passwortverlustes schnell erklärt.

Man-in-The-Middle (MiTM): Besonders populär ist die MiTM-Methode jüngst durch Firesheep geworden. Vor allem in fremden WLAN-Netzen besteht die Gefahr, dass unberechtigte mitlesen und Passwörter ausspähen. Hier würde eine verschlüsselte Verbindung erheblich mehr Nutzen, als ein Passwort, dessen Komplexität dem Mitsniffenden herzlich egal sein kann.

Phishing: Fällt der Benutzer auf eine gefälschte Seite herein, spielt die Passwortkomplexität keine Rolle mehr.

Brute Force: Soll ein Passwort durch reines Durchprobieren erraten werden, sind besonders schwache Passwörter wie 123456 oder der Benutzername als Passwort besonders gefährdet. Aber auch dies erfordert keine starken Passwörter. Eine Blacklist mit gängig schwachen Passwörtern und einer Prüfung auf den Benutzernamen vorwärts, wie rückwärts, verhindert die schlimmsten Passwortpatzer. Gepaart mit Wartezeiten zwischen den Logins und einer Begrenzung der insgesamt erlaubten Fehlschläge ist auch hier ein Erfolg unwahrscheinlich.

Educated guess: Gezieltes Raten durch Umfeldwissen lässt sich von allen Methoden am wenigstens vermeiden und kann tatsächlich zum Erfolg führen, zumal davon auszugehen ist, dass dem Ratenden der Benutzername bekannt ist. Hier wäre ein eingestreutes Sonderzeichen oder ein Ziffer tatsächlich hilfreich. Die Begrenzung der Loginversuche leistet aber ebenfalls gute Dienste, um ein zu häufiges Probieren zu unterbinden. Vor allem ist zu bemerken, dass Benutzer, die zu starken Passwörtern gezwungen werden, die Passwörter häufiger aufschreiben. Ich meine, hier ist abzuwägen, inwiefern das aufgeschriebene Passwort nicht ein höheres Risiko birgt, als ein aus dem Umfeld zu erratenes, schwaches. Vielmehr verführt das zufällig gefundene Passwort sogar zum Missbrauch. Der Zugang über das Umfeld des Benutzers ist nie auszuschließen. Schon gar nicht von Seiten der Webentwickler.

Rainbow-Tabellen: Ist die Datenbank der Webanwendung erst in fremden Händen, lassen sich mittels vorberechneter Hashes (Rainbow Tables) auch starke Passwörter knacken. Dagegen hilft der Einsatz von Salts, die wiederum auch schwache Passwörter schützen.

Natürlich sind starke Passwörter zu bevorzugen. An der Passwortsicherheit hängt aber mehr, als allein die Komplexität des Passworts. Vielmehr sind Softwareentwickler gefragt die Passwörter sicher abzulegen und die Loginprozedur so auszugestalten, dass automatisierte Angriffe an einer begrenzten Anzahl von Versuchen scheitern. Das muss nicht unbedingt mit einer Sperrung des Accounts enden. Eine zeitlich begrenzte Sperre hat bereits den gleichen Effekt. Letztendlich hat der Administrator den Transportweg mittels Https-Verbindungen abzusichern und der Benutzer ist gefragt, verantwortungsbewusst mit seinem Passwort umzugehen.

Update 18.12.10
Vor einigen Tagen sind dem US-Blogbetreibers Gawker u.a. die Benutzerdaten inkl. der DES-Verschlüsselten Passwörter abhanden gekommen. Die Hacker haben die Nutzerdaten veröffentlicht, was interessante Analysen zulässt. Die Passwörter wurden via DES-Hashes gespeichert. Soweit herauszulesen ist, wurden kein Salt verwendet, was eine einfache Dekodierung mittels Wörtbuch/Bruteforce ermöglicht. Unter den Daten waren auch die, des Gawker-Gründer Nick Denton, der das gleiche Passwort auch für seinen Google- und Twitteraccount verwendet hat.

Es lässt sich grundsätzlich nicht vermeiden, dass Benutzer ihre Passwörter mehrfach verwenden. Der Gawker-Fall zeigt aber deutlich, wo die eigentliche Gefahr liegt. Nämlich nicht etwa im schwachen Passwort, sondern darin, dass die Passwörter nicht gut genug gesichert wurden.

Einen nutzen können wir jedoch trotzdem daraus ziehen. Nämlich die Top250 ermittelten Passwörter für die Blacklist.

via heise, duosecurity

Mittwoch, 15. Dezember 2010

WindowBuilder und CodePro Profiler

Zwei Geschenke an die Community. Google übergibt WindowBuilder und CodePro Profiler an die Eclipse Foundation. Mit WindowBuilder lassen sich SWT- und Swingoberflächen zusammenklicken, CodePro ist ein Profiler. Beides lässt Eclipse bisher missen. Zwar gibt es einige GUI-Designer für Eclipse, aber spätestens bei Swing ist es mit überzeugenden Lösungen nicht weit her. Noch schlechter steht es um einen Profiler. Da gibt es eigentlich nur brauchbares bei den kommerziellen Tools. Wäre natürlich toll, wenn sich die Eclipse Foundation auch wirklich darum kümmern würde. Ich erinnere mich da an einige Plugins, die in den Aktualisierungen nicht mitgezogen wurden und irgendwann in der Versenkung verschwanden. Beide Tools halte ich für eine absolute Bereicherung, zumal die eigenen Bemühungen, bei der Entwicklung eines SWT/Swing-Designer (VEP), nie brauchbare Ergebnis zu Tage gefördert haben.

Insofern gute Nachrichten und ein dickes Danke an google. Die machen es einem manchmal wirklich schwer, sie nicht zu mögen.

Links:
CodePro: http://www.eclipse.org/proposals/tools.rat/
WindowBuilder: http://www.eclipse.org/proposals/tools.windowbuilder/ und http://code.google.com/intl/de-DE/javadevtools/download-wbpro.html

via it-republik.de

Paygames für Linux

Ich bin immer wieder erfreut, wenn auch kommerzielles für Linux entwickelt wird. Ein Spielebundle für Linux, Mac und Windows gibt es derzeit auf Basis einer freiwilligen Spende bei The Humble Indie Bundle. Ich bin zwar für Spiele nur bedingt zu haben, diese wollte ich aber gern ausprobieren. Von den fünf Spielen laufen immerhin vier auf Anhieb. Nur der Cortex Commander wollte, trotz 64bit Installer, auf meiner Maschine leider nicht. Die anderen vier Spiele habe ich angespielt und ich bin sehr angetan von der Ideenvielfalt.

Braid: Ein Jump and Run der besonderen Sorte. Weil Videos manchmal mehr als viele Worte sagen, hier der Trailer zum Game.




Machinarium: Definitiv ein Highlight, wenn man das Adventure-Genre mag.




Osmos: Ein Spiel, mit dem man Stunden verbringen kann, ohne es zu merken. atmosphärisch und suchterregend wären die beiden Attribute, die mir zuerst einfallen würden.




Refenge of the Titans: Passt am besten in die Kategorie Retrogames. Ebenfalls schön gestaltet, aber ehrlich gesagt nicht mein Fall.



via stadt-bremerhaven.de

*Update 22.12.10*
Echt fair ist übrigens, dass Humbler Bundle sich entschieden hat, einfach die Spiele vom letzten Bundle auch noch dazuzugeben. Außerdem bekommt man die noch auf seinen Steam-Account. Sowas habe ich aber sowieso nicht.

Freitag, 10. Dezember 2010

Swing Komponenten in XPS Drucken

Java und Drucken ist ja so eine Sache, mit der ich mich bereits viel herumgeärgert habe. In einem aktuellen Fall werden Swingkomponenten ausgedruckt. Das funktioniert soweit ganz ordentlich. Einzig, wenn man den Microsoft XPS-Drucker verwendet, erscheint ausschließlich die letzte Komponente im Ausdruck - der Rest fehlt. Zeichnet man ohne Swing-Komponenten auf dem Graphics-Object des XPS-Drucker, erscheint das Ergebnis wie erwartet. Woran es nun genau gelegen hat, vermag ich auch nicht zu sagen. Ich bin letztendlich darauf hängen geblieben, dass der Ausdruck auf dem XPS-Drucker korrekt herauskommt, wenn man nach dem paintAll der Swing-Komponenten ein drawLine auf das oberste Graphics-Object ausführt. Besonders hinterhältig ist immer die Aussage der Benutzer, dass ganze würde ja schließlich mit Word gut funktionieren. Das sind die Stellen, an denen sich die Maschinenferne von Java rächt. Man hat im Grunde kaum Manipulationsmöglichkeiten um so einem zickigen Druckertreiber beizukommen. In diesem Fall war es ja zum Glück recht unkompliziert.

Mittwoch, 8. Dezember 2010

Bibliotheken Guava und op4j

Guava: Die Google Collections Library ist veraltet, seit einiger Zeit benutzt man Guava. Das Guava-Projekt entwickelt die Google-Bibliotheken weiter. Die Bestandsfunktionalität der Google Collections bleibt erhalten, es sind aber neue Funktionalitäten hinzugekommen, Bugfixes eingearbeitet und Performanceverbesserungen durchgeführt worden. Die gesamte Bibliothek umfasst inzwischen weitaus mehr, als nur Collections. Was es da inzwischen alles gibt, muss ich bei nächster Gelegenheit mal evaluieren.

*Update 23.01.11*
Eine ganz ordentlichen Einblick in die Möglichkeiten von Guava gibt es bei Thomas Ferris Nicolaisen.

op4j: Eine Bibliothek die den Einsatz der Fluent-Schreibweise schmackhaft macht. Nach kurzer Eingewöhnung kann man damit semantisch sehr gut lesbaren Code erzeugen.

Sonntag, 5. Dezember 2010

10 typische Fehler in Enterprise-Java-Anwendungen

Eine Teil der beschriebenen Fehler lassen sich auch auf alle anderen Java-Anwendungen transportieren. Den Vortrag hält Eberhard Wolff auf der W-JAX 2009. Die Fehler, die er beschreibt, sind viel mehr Designschwächen, die man tatsächlich in sehr vielen Anwendungen wiederfindet. Alles in allem ein außerordentlich empfehlenswerter Vortrag!

Donnerstag, 2. Dezember 2010

Java ist auch eine Insel die 9te

Seit November ist es draußen. Das Buch, dass vermutlich jeder, der sich jemals mit Java befasst hat, zumindest dem Namen nach kennt. Von "Java ist auch eine Insel" gibt es die 9te, überarbeitete Fassung zum online- und offline lesen, sowie als Buch zum Kaufen.

http://openbook.galileocomputing.de/javainsel9/