balumba.org

Bang! Bang!

Lieblingsmusik 2011

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.

Regenbogen

Manchmal, in ganz seltenen Momenten kann auch der Potsdamer Platz in Schönheit strahlen:

Junits Parameterized Test-Runner Und Die Reflections-Bilbiothek

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:

1
2
3
4
5
6
7
8
9
10
public interface EntityIf extends Serializable {
    Long getId();

    Date getCreated();

    UUID getUUID();

    @Override
    String toString();
}

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    @Parameters
    public static Collection dataParameters() throws InstantiationException, IllegalAccessException {
       Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(
                    ClasspathHelper.getUrlsForPackagePrefix("org.balumba.project")
                 )
                .setScanners(new SubTypesScanner()));
        Set<Class<? extends EntityIf>> subTypes = reflections.getSubTypesOf(EntityIf.class);
        List<Object[]> result = new ArrayList<Object[]>();
        for (Class cls : subTypes) {
            if (Modifier.isAbstract(cls.getModifiers())) {
                continue;
            }
            Object[] entry = new Object[]{cls.newInstance()};
            result.add(entry);
        }
        System.out.println();
        return result;
    }

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.

Aufregende Zeiten

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.

Das Leben kann schön sein.

Maven Dependency Ranges

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:

1
2
3
4
5
6
 <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>[3.8,4.0)</version>
     <scope>test</scope>
 </dependency>

Würde die aktuelleste JUnit3 Release nutzen, jedoch keine aktuellere Release. Das Beispiel ist natürlich aus der Dokumentation von Maven geklaut.

1
 <version>[2.0,)</version>

würde dementsprechend die aktuellste Version größer 2.0 verwenden. Weitere Informationen zu den Dependency Ranges stehen in der Dokumentation.

Blog-Restart

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.

Change is good.

Lieblingsmusik 2009

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:

Und wie sieht es bei Euch aus?

Opportunism Hurray!

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.

Pfui.

(via Tim)

So Ein Tag

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?

java.util.prefs.Preferences Unter Windows

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:

HKEY_CURRENT_USER\Software\Javasoft\Prefs<Package>

Ja ich weiß, nichts großartiges, aber vielleicht erspare ich damit jemanden das Suchen.