Für 2010 habe ich es versehentlich nicht getan, aber dieses Jahr ist ist natürlich wieder ein
Rückblick fällig. Wie schon in den letzten Jahren hat die Reihenfolge nicht unbedingt eine
Bedeutung.
Erschreckt stelle ich fest, dass ich für 2011 nur noch auf fünf Alben komme, das war 2008 und
2009 noch anders. Liegt das daran, dass die Qualität der Musil im letzten Jahr einfach abgenommen
hat, oder wende ich nicht mehr genug Zeit für mein einstmals liebstes Hobby auf? Ich hoffe, dass es
dieses Jahr wieder besser wird.
Im Rahmen eines Projektes stieß ich auf ein ein interessantes Problem: Alle meine mit Hibernate persistierten Entity-Klassen sollen ein Interface implementieren, das folgendermaßen aussieht:
Um das Problem noch etwas interessanter zu gestalten, wurde eine abstrakte Klasse geschrieben, die
eben dieses Interface implementiert und von dem dann alle Wald- und Wiesen-Entities ableiten können.
Auf diese Weise soll das “Copy ‘n’ Waste threshold” reduziert werden.
Um sicher zu stellen, dass die Entities im System dieses Interface nicht nur implementieren, sondern
sich auch so verhalten, wie es ursprünglich gedacht war, sollen alle Entities mit einem Unit-Test, der
die im Interface definierten Methoden testet, eben darauf geprüft werden. Mit JUnit ist dieser
Test schnell geschrieben: JUnit 4 bietet mit dem ”Parameterized Test Runner” die Möglichkeit,
diese einmal geschriebene Unit-Tests gegen zur Laufzeit generierte Testdaten auszuführen. Dazu muss
eine Testklasse folgende Bedingungen erfüllen:
Die Test-Klasse muss mit dem Parameterized Test-Runner ausgeführt werden. Dies wird erreicht, indem man die Testklasse mit @RunWith(Parameterized.class) annotiert.
Eine statische Methode, welche die Test-Daten erzeugt.
Ein einziger Konstruktor, der als Parameter die erzeugten Test-Daten akzeptiert und diese für die Tests vorhält.
Natürlich mindestens eine Test-Methode (annotiert mit @Test)
Die statische Methode, welche die Test-Daten erzeugt, muss mit @Parameters annotiert werden und eine
Collection von Arrays zurück geben. Die Anzahl derElemente eines Arrays muss der Anzahl an Parametern
des Konstruktors entsprechen, denn die Arrays werden genutzt um zur Laufzeit der Klasse die Testobjekte
zu erzeugen.
JUnit 4 stellt also eine Möglichkeit zur Verfügung, mit relativ einfachen Mitteln Tests zur
Laufzeit dynamisch zu erzeugen. Es fehlt nur noch eine Möglichkeit, zur Laufzeit alle mein Interface
implementierenden Klassen zu identifizieren. Es stellte sich heraus, dass das schwieriger zu
realisieren war, als erwartet. Die JVM bietet nämlich von Hause aus keine einfache Methode, um alle zur
Laufzeit im Classloader zur Verfügung stehenden Implementierungen einer Klasse zu ermitteln. Auch das
fantastische Buch ”Java Reflection in Action” zeigte keinen gangbaren Weg auf.
Zur Hilfe kam die Bibliothek Reflections, die unter der LGPL bei Google-Code bezogen werden
kann. Reflections scannt den Classpath des einbindenden Projekts, indiziert die Metadaten der Elemente
des Classpaths und stellt diese für Abfragen bereit. Die oben beschriebene Suche nach allen (indirekt,
also auch in zweiter Generation) ein Interface implementierenden Klassen als Daten-Provider für meinen
Unit-Test mit den oben beschriebenen ”Parameterized Test Runner” sieht mit dem Einsatz der
Bibliothek wie folgt aus:
Von Bedeutung sind hier besonders die Zeilen drei bis acht, die mittels des ConfigurationBuilder
die Reflections Bibliothek konfiguriert. Der verwendete SubTypeScanner scannt den Classpath nach
Superklassen und Interfaces, und stellt diese Informationen für spätere Abfragen bereit. Die Zeile
acht liefert dann ein Set aller Sub-Typen des EntityIf-Interfaces. Zeile 12 stellt sicher, dass
keine abstrakte Klasse in den Test-Daten landet, denn die kann ja vom Test dann nicht instantiiert
werden. Hier wird die normale Reflections-Api von Java genutzt, Modifier ist eine Klasse, die Zugriff auf die Modifier einer Klasse liefert.
Mit Hilfe der abgebildeten dataParameters()-Methode ist es nun möglich mit den üblichen Test-Methoden
sicher zu stellen, dass sich alle ein Interface implementierenden Klassen so verhalten, wie es vom Rest
der Applikation benötigt. wird.
Die Reflections-Bibliothek bietet auch ein Maven-Plugin, mit der die Metadaten zur Build-Zeit ermittelt
werden können, um dann zur Laufzeit auf das Scannen verzichten zu können, allerdings habe ich das
bisher noch nicht probiert. Einen kleinen Wermutstropfen scheint es noch zu geben: Die Bibliothek hat
schon seit geraumer Zeit keine Aktualisierung mehr erfahren, es ist nicht klar, ob es mit diesem
Projekt noch lang weiter geht. Das wird aber die Zeit zeigen.
Samstag war ich mit angeblich 120.000 anderen gegen Kernenergie demonstrieren, am Sonntag durfte ich beobachten, wie die CDU das Ländle verliert und die FDP auf dem Weg in die Bedeutungslosigkeit voran stürmte und ich muss sagen ich freue mich.
Ich freue mich darüber, dass Kernenergie in diesem Land ganz eindeutig keine Zukunft hat. Ich freue mich darüber, dass die Feinde der Freiheit (FDP) ganz offenbar derzeit mit ihrer Politik in diesem Land nicht gewünscht sind. Und ich freue mich darüber, dass wir auf Sommerzeit umgestellt haben und der Frühling endlich kommt.
Meine Hassliebe zu Maven begleitet mich nun schon eine ganze Weile, aber ich halte alle anderen Build-Systeme die ich kenne (na gut, unter Java ist es nur Ant) für noch viel schlimmer.
Dieser Unwille sich mit Maven näher als unbedingt nötig auseinander zu setzen hat auch dazu geführt, dass mir bis jetzt nie klar wurde, dass es möglich ist, für Abhängigkeiten des Projektes Versionsbereiche anzugeben, also: “Nimm die aktuellste Version größer X aber nicht aktueller als Y.” Das geht recht einfach, nämlich folgendermaßen:
Gut. Die Twitter Tools haben aufgehört zu funktionieren, das liegt natürlich daran, dass Twitter die Art der Authentifizierung umgestellt hat und nicht an den hervorragenden Twitter Tools, führt aber dazu, dass meine Tweets nicht mehr automatisch in regelmäßigen Posts hier im Blog abgeladen werden. Nach kurzem hadern mit der Situation hat mir das sehr gut gefallen, zwingt es mich doch, mich endlich wieder mit diesem, meinem, Blog zu beschäftigen. Ich kann die Twitter Tools wieder konfigurieren, oder sie auslassen und mich dann wieder mehr mit dem eigentlichen bloggen beschäftigen. Das wollte ich eh’ schon länger und habe beschlossen dieser erzwungenen Änderung jetzt mit verstärktem Einsatz für dieses, mein Blog zu begegnen.
In den kommenden Wochen werde ich also hier die Post-Frequenz deutlich in die Höhe schrauben - zugegeben, das wird nicht schwer - und hier Artikel einstellen, die sich um Sachen drehen, die mich interessieren, Software-Entwicklung im Allgemeinen, Java, Perl und Musik. Was mir halt so wichtig sein wird. Auch wenn dieses Blog keine Leser hat.
So, es ist auch dieses Jahr wieder Zeit für Jahresrückblicke. Wie es in diesem Blog Tradition ist (na gut, das zweite Jahr in Folge) hier meine zehn Lieblingsalben dieses Jahr. Auch dieses Mal ist die Reihenfolge nicht unbedingt aussagekräftig:
Ich bin ja kein Freund der FDP, deshalb fällt es mir natürlich immer leicht, über sie zu meckern. Diese Äußerung des Bundestagskanidaten Jörg Behlen ist so eklig und an Opportunismus kaum zu überbieten, dass ich nicht anders kann als hier meinem Missfallen öffentlich Ausdruck zu verleihen. Er stellt das Zensursula-Gesetz in Frage und wird sich als “überzeugter Liberaler” dafür einsetzen, das Gesetz wieder abzuschaffen. Er stellt sogar einen Gang vor das Bundesverfassungsgericht in Aussicht, aber nur wenn eine Regierungsbeteiligung der FDP in der kommenden Legislaturperiode ausbleibt.
Was ist denn Heute los? Das Bombodrom wird endgültig aufgegeben, mein Projekt nimmt Gestalt an und in der U-Bahn werde ich von einem ausgesprochen höflichen Fahrkartenkontrolleur kontrolliert?
Da ist doch irgendwas Faul! Was kommt denn jetzt als nächstes? Die zwei Staaten Lösung im nahen Osten? Sofortiger Atomausstieg?
Nutze ich Windows, fühle ich mich immer etwas eingeschränkt und alles geht etwas langsamer. Diesmal jedoch bin ich sicher, dass es nicht mein Fehler war :-)
Während ich meine Diplomverteidigung vorbereitete kam ich in die Situation, dass ich unter Windows (Mein Freund Benni war so nett mir sein Netbook zur Präsentation zur Verfügung zu stellen) die von JMonkeyEngine genutzten Voreinstellungen zu löschen. Einmal an der falschen Stelle geklickt und zack, meine Software startete immer in der falschen Auflösung. JmonkeyEngine nutzt für seine Voreinstellungen die Klasse java.util.prefs.Preferences. Das macht ja soweit auch Sinn, dafür ist sie ja da. In den Javadocs steht auch, dass diese Klasse die Voreinstellungen mit den vom jeweiligen Betriebssystem vorgesehenen Mitteln speichert. Das es sich unter Windows hierbei um die Registry handelt, schwante mir erst nach knapp einer Stunde verzweifeltem Suchen. Falls es Euch als UNIX-Nutzern auch mal so geht wie mir: die Voreinstellungen finden sich in der Registry unter: