Tsunami Disaster

I was shocked and speechless, as within a few days the death toll from the Tsunami rose from 10,000 to over 130,000, and still rising. Please donate!

Der Spring Container (oder: Dependency Injection)

Die Beispielanwendung (und warum Sie beim Start eine Warnung bekommen)
Die Beispielanwenung benötigt Java Webstart zum Laufen – und wenn Sie ein Java Entwickler sind, haben sie die Software auch schon installiert. Leider brauche ich mehr zugang zu Ihrem System, als der normale SecurityManager zuläßt. Um genau zu sein, Spring benutzt Reflektion (getDeclaredConstructors()) um Objekte zu instantiieren. Daher müssen alle jars zertifiziert sein. Das habe ich gemacht, allerdings kann ich mir im Moment keinen Schl¨ssel von Verisign leisten, und habe meinen eigenen Schlüssel erstellt, der dementsprechend in keiner zentralen Datenbank zu finden ist.

Spring Demo Ausführen >>
Code runterladen >>

Zunächst einmal: Spring ist wesentlich mehr als der Container den ich gleich beschreiben werde. Spring bietet Aspect Oriented Programming (AOP), Transaktionsmanagement, Metadata-Unterstützung (ähnlich wie JDK 1.5 Metadata, orthogonal zu XDoclet), und viel Unterstützung für Datenbankoperationen (inklusive der Unterstützung von O/R-Mappern wie Hibernate oder JDO). Die Englische Onlinedokumentation ist excellent!

Das klingt zwar so, als gäbe es hier keine Struktur; aber trotz der Vielfalt ist Spring seinen Grundprinzipien treu: (1) Den Programmierer nicht einschränken; (2) Guten Programmierstil unterstützen; (3) Das Rad nicht neu erfinden.

BeanFactory und ApplicationContext

Der grundliegenste Aspekt von Spring ist die BeanFactory – der ApplicationContext ist lediglich eine erweiterte BeanFactory mit Unterstützung für AOP, Internationalisierung, etc. Die Beispielanwenung benutzt eine XMLBeanFactory, und in der Regel werden die Beans per XML definiert. Schau’n wir uns doch erst einmal an, wie eine Bean Definition aussieht, und untersuchen dann, warum so etwas sinnvoll ist.

Die BeanFactory kann jede Art von Objekt enthalten, aber sie ist besonders für JavaBeans geeignet. Zum Experimentieren habe ich die folgende Klasse erstellt:

public class SampleBean { private String name = "(no name)"; private Set friends = new HashSet(); public Set getFriends() { return friends; } public void setFriends(Set friends) { this.friends = friends; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return name + friends; } } 

Die Klasse ist eine JavaBean, denn sie hat (1) einen Default Konstruktor und (2) Setters und Getters, die dem JavaBean Standard entsprechen. Wenn wir so eine Klasse im Spring Container erstellen wollen, dann stecken wir das folgende XML in die Containerdefinition:

<bean id="aSampleBean" class="de.jastram.SampleBean"> <property name="name"> <value>Sample Bean Name</value> </property> <property name="friends"> <set> <value>123</value> <value>Hello, World</value> </set> </property> </bean> 

Das können Sie gleich mit der Beispielanwendung ausprobieren! Wenn auf dem linken Tab das XML editiert wird, werden die Änderungen auf dem rechten Tab reflektiert.

Alles Singletons

Soweit, so gut. Wir können also über XML Java Objekte erstellen. Wir kommen auch leicht an die Objekte ran – das Interface BeanFactory hat methoden um Beans per Name zu finden. Wenn wir also eine Referenz zu unserer BeanFactory verfügbar halten, kommen wir an unsere Beans ran. Normalerweise haben wir nur Singletons im Container – und das wollen wir normalerweise auch. Allerdings ist es auch möglich, “Prototypen” im Swing Container zu haben – dann wird bei jedem Aufruf von getBean() ein neues Objekt erstellt. Dazu wird einfach singleton="false" dem <bean> Tag hinzugefügt.

Eine typische Anwendung benutzt ein DataSource Objekt, das mit einer Datenbank assoziiert ist. Es wird einmal erstellt, konfiguriert, und kann dann von überall dort benutzt werden, wo der Container verfügbar ist.

Aber gerade ein DataSource Objekt wollen wir nicht unbedingt per Constructor erstellen, oder? Und hier glänzt Spring wieder: Es gibt weitere Möglichkeiten, Objekte zu erstellen: Factories. Factories sind ganz normale Objekte. Aber diesmal ist das Objekt nicht das Endprodukt, sondern der “Objektproduzent”. Zum Beispiel, die Klasse java.lang.System hat die statische Methode currentTimeMillis(), die wir als Factory benutzen können – probieren wir das doch einfach mal aus: Kopieren Sie das folgende XML in die Beispielanwendung:

<bean id="systemTimeFactory" class="java.lang.System" factory-method="currentTimeMillis"/> 

Wenn wir uns das resultierende Objekt anschauen, was für ein Klassentyp ist es? Die Antwort ist Long (und nicht System). Übrigens können wir immer noch an das Factoryobjekt herankommen, wenn wir unbedingt wollen, indem wir einfach ein “&” vor den Namen setzen. Also factory.getBean("&systemTimeFactory") gibt uns die Factory.

In diesem Beispiel ist die Factorymethode eine statische Methode – Spring hat selbstverständlich auch die Möglichkeit, eine (nicht statische) Methode eines Singletons als Factorymethode aufzurufen.

Und jetzt…?

Wozu das ganze? Gut strukturierte Anwendungen haben eine Reihe von Singletons, die untereinander verbunden sind. Wie oben schon erwähnt, haben wir fast immer eine DataSource um mit einer Datenbank zu sprechen. Die Logik, die mit der Datenbank kommuniziert, ist normalerweise in Data Access Objects (DAOs) untergebracht. Die Geschäftslogik lebt ebenfalls in Singletons, die nur zu den DAOs sprechen, und darauf sitzt normalerweise eine weitere Schicht (oft Servlets), die zu mit der Geschäftslogik kommunizieren, und die Benutzeroberfläche bilden. Es ist also einzusehen, dass wir viel mit Singletons arbeiten, die untereinander kommunizieren. Spring macht die Verknüpfung dieser Singletons ungleich einfacher.

Und existierende Techniken? Applikation Server wie Tomcat sind zwar ähnlich leistungsfähig, aber beschränken sich auf Servlets im Container. Ein Riesenvorteil von Spring ist, daß es mit POJOs arbeiten kann. Und der Unterschied ist noch viel extremer, wenn wir uns EJB anschauen, daß ohne Codegenerierungssoftware kaum zu bewältigen ist!

Aber die Authoren von Spring sind sich dieser Technologien natürlich bewußt, und haben sehr darauf geachtet, daß Spring problemlos mit diesen Technologien zusammenarbeiten kann – es ist also keine “entweder – oder” Entscheidung notwendig.

Der Spring Container bringt den Anwender dazu, besseren Code zu schreiben. Plötzlich ist klar, wie wir Objekte konfigurieren: Mit JavaBean Setters. Und wenn alle Komponenten unseres Systems plötzlich Setters für die Konfiguration haben (die am Besten auch noch Interfaces wie DataSource statt Klassen als Argument haben), dann wird auch das Testen dieser Komponenten mit Unit Tests und Mock Objekten plötzlich viel einfacher.

Weitere Juwelen in Spring

Ist Ihnen aufgefallen, daß wir <value>1234<value> schreiben, und ein Integer Objekt erhalten? Wie geht das? Der Container hat eine erweiterbare Infrastruktur, die Text in Objekte umwandelt.

Manchmal gibt es nur ein einziges Objekt von einem bestimmten Typ im Container – zum Beispiel nur eine einzige DataSource. In diesem Fall können wir Spring’s auto-wiring (automatisches verbinden) benutzen, um automatisch alle Setters, die eine DataSource als Argument benutzen, mit diesem Objekt aufzurufen. (einfach autowire="byType" der Bean hinzufügen). Auto-wiring per Name ist auch unterstützt (autowire="byName").

Ein heißes Thema heutzutage sind “Interceptors” (Abfänger) – ein zentraler Aspekt von AOP. Ein Interceptor kann vor oder nach dem Aufruf einer Methode eingreifen. Zum Beispiel könnten wir einen Sicherheits-Interceptor entwerfen, der vor dem Aufruf einer Methode prüft, ob der Benutzer genug Befugnisse hat. In einem traditionellem Programm müßte jede Methode extra Code für diesen Zweck haben, oder wir müßten eine gute Proxy-Architektur haben. Mit Spring AOP können wir mit RegExps definieren, welche Methoden abgefangen werden sollen, und den Spring Container informieren, diesen Interceptor zu aktivieren. Die abgefangenen Objekte brauchen davon überhaupt nichts zu wissen!

Schlußbemerkung

Spring hat unglaublich viel für die Enterpriseentwicklung zu bieten – und es ist unglaublich unaufdringlich dabei. Es ist vor allem sehr einfach, Spring hier und da in einer existierenden Anwendung einzuführen, und dann langsam den Einfluß von Spring zu erweitern. Spring ist kein Allheilmittel für alles – aber es ist erfreulich, so ein Leichtgewicht im Reportoir als Alternative zu EJB et. al. zu haben,

KDE or Gnome…?

Why KDE? Because (1) it’s easier to customize, and (2) more like Windows. Let me elaborate:

(1) Maybe I didn’t do things right, but the ability to configure look and feel, font sizes, widget sizes was quite awkward in Gnome. While it is possible to select a specific Theme, it’s quite difficult to fine-tune it without editing configuration files. Well, I don’t mind editing the configuration file for my mail server, because I often access my mail server through a ssh session. But for a system with the only purpuse of giving me graphical access, I’d rather have the ability to fine-tune the system quickly and efficiently within this system. On that account, KDE beats Gnome by far.

(2)Windows… I am not a big fan of Microsoft, and I think they do a bad job on the server side. But they do understand the desktop! There are few things that I miss on Windows (like multiple desktops), and I gut used to their keybindings, and am unwilling to learn something new without a good reason. So I was pleased to see that KDE supported the Windows-Key right out of the box.

Gnome apps under KDE

My biggest struggle was to get Gnome apps look right under KDE. And I am dependent on Gnome (or more acurately, GTK) apps, specifically Firefox, Gimp and Eclipse.

I tried Debian and Suse, and on both distributions the fonts were huge, and the empty space around widgets unproportionally wide, eating up all my real estate. I tried to tinker with the gtk configuration files (.gtkrc and .gtkrc-2.0), but eventually gave up (I’ll tell you why later on).

For a while, I was limping along with workarounds. I used a different Firefox Theme. It didn’t look great, but saved me real estate. I was using the Motif version of Eclipse. Again, it saved me real estate, but it looked horrible

Suse screws up Gnome

When I tried to find some advice online once more, I finally found out why I didn’t go anywhere by editing my .gtkrc files: Suse designed their own hook to make sure Gnome applications would look good under KDE – but they didn’t take users changing the widget set into account, and screwed things up. How to fix it is documented here. Essentially, you have to edit /opt/kde3/bin/startkde to allow the .gtkrc file to be picked up! It looks like an ugly hack to me, but at least it works.

Now I set my .gtkrc and .gtkrc-2.0 files to use the “Simple” theme, and things started to look much, much better! The fonts were still a little too big for my taste, but I could fix that by adding the following entry to my .gtkrc* files: gtk-font-name = "Sans 7".

Now I feel that my Linux System is truly usable on a daily basis, but fixing these things made quite a difference. I hope these notes will be useful for somebody – including myself the next time I set up a Linux box.

Economist calls Bush “incompetent”

To be fair, they call Kerry incoherent, but endorse him nevertheless. The Editorial talks about “two deeply flawed men”. Interestingly, they think that Bush’s biggest mistake was “in dealing with prisoners-of-war by sending hundreds of them to the American base at Guantánamo Bay in Cuba, putting them in a legal limbo, outside the Geneva conventions and outside America’s own legal system.” On the other hand they state that “invading Iraq was not a mistake” – something I disagree, because in my opinion, American military force could have decreased the risk of terrorism elsewhere much more effectively – namely to resolve the Israeli-Palestinian conflict. And the Economist acknowledges that “Israel and Palestine remain in their bitter conflict, with America readily accusable of bias.”

Kerry, on the other hand, receives some harsh words, too, and on foreign affairs they consider him a “ruthless opportunist.” Nevertheless, they acknowlege that his actions (rather than his words) “speak well of his judgment.” I wish him good luck on Tuesday.

Unit Tests: Wohin damit…?

Warum ist es überhaupt wichtig, wo wir die Unit Tests unterbringen? Weil wir die kleinste “Einheit” (Unit) des Systems testen wollen, und die kleinste Einheiten (Klassen, Methoden und Constructoren) sind oft package private oder protected, und nicht immer public. Um leicht auf diese Elemente zugreifen zu können, sollte der Testcode in der selben Package sein. Das gibt uns zwar keinen Zugang zu privaten Variablen und Funktionen, aber wenn die zum Testen notwendig wären, sollte die Architektur der Klasse überprüft werden. Die naive Klassenstruktur wäre dann folgendermaßen:

 src/de/jastram/unit/MyClass.java src/de/jastram/unit/MyClassTest.java 

Mir gefällt diese Struktur nicht (und viele andere Entwickler stimmen mir zu), weil nun der Ordner normalen und Testcode mischt. Das ist aus vielerlei Gründen schlecht: JavaDoc würde die Testklassen enthalten, es ist schwierig, eine Distributionsdatei ohne Testklassen zu erstellen, usw. Diese Probleme könnten zwar mit einem geschickten Ant Skript gelöst werden, aber das Resultat ist nicht elegant, und für neue Entwickler schwer zu verstehen.

Die zweite Lösung gfällt mir wesentlich besser, und ist meine Empfehlung: Testklassen sind in der selben Package, aber in unterschiedlichen Ordnern:

 src/de/jastram/unit/MyClass.java test/de/jastram/unit/MyClassTest.java 

Alle IDEs die ich kenne, unterstützen diese Struktur, und Ant Skripte sowieso. Es ist nicht unüblich, eine Reihe von Sourceverzeichnissen zu haben. Jetzt ist es kinderleicht, JavaDoc zu erzeugen, oder eine JAR ohne die Testklassen zu bauen. Aber diese Struktur läßt zwei Fragen offen: (1) Was tun, wenn wir aus irgendeinem Grund doch Zugang zu privaten Elementen haben wollen, und (2) ist diese Struktur nicht ein bißchen übertrieben für kleine Projekte?

Für Punkt 1 gibt es eine Lösung (auch ohne Reflektion): Wir bringen die Testklasse einfach als static Memberklasse in unserer Hauptklasse unter! Das ist auch eine gute Struktur für Demonstrationen, weil wir nur eine einzige Klasse haben:

 src/de/jastram/unit/MyClass.java 

Und wo ist die Testklasse? In der selben Datei – der Code sieht etwa folgendermaßen aus:

public class MyClass { ... public static class Test extends TestCase { ... } } 

Und wie gesagt, nun können wir sogar auf die privaten Elemente zugreifen. Wie gesagt, diese Architektur muß mit Vorsicht genossen werden, und ist nicht für größere Projekte geeignet. Es ist (fast) unmöglich, das Programm ohne den Testcode zu verarbeiten, es ist noch nicht einmal möglich, die Datei ohne den Testcode zu drucken! Dennoch, für kleine Tests und Demos ist das eine prima Architektur.

Gibt es vielleicht noch bessere Ansätze zur Codeorganisation? Schreibt Eure Meinung weiter unten ins Formum!

Weapons of Math Instruction

At a morning press conference, Attorney General John Ashcroft said he believes the man is a member of the notorious al-gebra movement. He is being charged by the FBI with carrying weapons of math instruction. “Al-gebra is a fearsome cult,” Ashcroft said. “They desire average solutions by means and extremes, and sometimes go off on tangents in a search of absolute value.

“They use secret code names like ‘x’ and ‘y’ and refer to themselves as ‘unknowns,’ but we have determined they belong to a common denominator of the axis of medieval with coordinates in every country. As the Greek philanderer Isosceles used to say, ‘there are three sides to every triangle.'”

When asked to comment on the arrest, President Bush said, “If God had wanted us to have better weapons of math instruction, He would have given us more fingers and toes.”