Thema der Woche: Java™ 6u10 – Java6u13

In der letzten Java™ 6 Updates sind einige Neuigkeiten hinzugekommen. Einige sind JavaFX geschuldet.

Java 6u14 ist noch nicht fertig. Es gibt nur ein „Java™ Platform, Standard Edition 6u14 Binary Snapshot Releases“. Die Anzahl der gefixten Bugs ist groß. Lese dazu  http://download.java.net/jdk6/ und http://tutorial.fyicenter.com/out.php?ID=3688.

Na endlich: JDK 7 feature list, build and integration schedule

Mark Reinhold schreibt auf seinem Blog:

At Devoxx back in December I presented a list of candidate features for JDK 7(video, interview); more recently, at FOSDEM, I discussed that list as well as the high-level schedule and the means by which we plan to deliver the release (slides, audio/video). The high-level schedule is now available on the JDK 7 Project page in theOpenJDK Community along with a detailed feature list, the near-term build and integration schedule, and the long-term, build-by-build calendar. The JDK 7 feature list, like that of any large software project, is provisional and subject to change based upon new information and new proposals. Who Many of the planned features will be implemented by Sun engineers; the rest will be contributed from outside Sun. We’ll shortly define a process by which additional features can be proposed—so long as you’re willing to write not just the code but also the necessary tests and specification material. There will also be a simpler, lighter-weight process for smaller changes. Where Regardless of who writes the code, the expectation is that all development will take place in the open, either in the JDK 7 Project, in some other OpenJDK Project, or elsewhere. What about the JCP? The JDK 7 Project is creating a prototype of what might—or might not—wind up in the Java SE 7 Platform Specification. When the SE 7 Platform JSR is submitted then the features under development in JDK 7 will be proposed for inclusion therein, except for those that are VM-level or implementation-specific.

Der Kalender gibt Ende Februar an.

M8 2010/02/12 – 2010/02/18 b95

Die Feature-List ist interessant aber ich denke, dass einiges im Detail noch offen ist:

  • JSR TBD: Small language enhancements (Project Coin)
  • JSR 296: Swing application framework
  • Swing updates

Einführung in den EventBus

Was ist EventBus?

  • Die Idee vom EventBus https://eventbus.dev.java.net/ ist schnell in einem Satz beschrieben:
    • Biete einen Publish/Subscribe-Ereignisdienst für Applikationen an, die innerhalb einer JVM laufen.
    • Anders als also JMS, funktioniert EventBus nur in einer JVM, aber nicht über Rechnergrenzen.
  • Ereignisbehandlung wird üblicherweise über Observer/Observable oder über Listener realisiert.
    • Listener sind aber lästig zu schreiben: Man benötigt XXXEventListener Schnittstellen und Implementierungen, addXXXListener(), removeXXXListener() und fireEventListener() Methoden und vielleicht XXXEvent-Klassen.
  • EventBus vereinfacht das und mit zwei Typen und drei Methoden ist ein erstes Beispiel programmiert.

Erstes Beispiel


import org.bushe.swing.event.EventBus;
import org.bushe.swing.event.EventSubscriber;

class Observer
{
Observer()
{
EventBus.subscribe( Object.class, new EventSubscriber<Object>() {
@Override public void onEvent( Object evt ) {
System.out.println( evt );
}
} );
}
}

public class First
{
public static void main( String args[] )
{
new Observer();
EventBus.publish( "Hallo Welt" );
}
}

Analyse

  • EventBus.publish( Object ) sendet ein Ereignis an alle Interessenten aus.
  • EventBus.subscribe( Class, EventSubscriber ) meldet für einen speziellen Klassentyp einen Listener an.
    • Das besondere: Es ist hierarchisch. Wir senden mit EventBus.publish( „Hallo“ ) einen String, aber da String eine Unterklasse von Object ist, bekommt unser „Alles“-Listener die Nachricht.
    • EventBus.unsubscribe() meldet den Interessenten wieder ab.
  • Der EventSubscriber ist generisch deklariert, so dass es bei EventSubscriber<Object> somit onEvent( Object evt ) heißt.

Hierarchien

  • Mit der Möglichkeit Event-Hierarchien zu bilden gibt es eine große Flexibilität.
  • So horcht folgendes auf alle IOException-Events: EventBus.subscribe( IOException.class, new EventSubscriber() { … EventBus.publish( new FileNotFoundException() );
  • Ist dieses Matchen nicht gewünscht, verwendet man statt EventBus.subscribe() die Methode EventBus.subscribeExactly().

Hierarchien bei Generischen Typen (1)

  • Bei Generics funktioniert ein .class nicht wie erwartet.
    • Es liefert System.out.println( new Holder<String>().getClass() ); und System.out.println( new Holder<StringBuffer>().getClass() ); immer nur class javax.xml.ws.Holder.
  • Was passiert bei EventBus.subscribe( Holder.class, new EventSubscriber() { … und EventBus.publish( new Holder<String>(„String value“) ); EventBus.publish( new Holder<Date>( new Date() ) );
  • In beiden Fällen wird der Listener benachrichtigt.

Hierarchien bei Generischen Typen (2)

  • Soll eine Trennung aufgrund des generischen Typs stattfinden, lässt sich auf ein java.lang.reflect.Type anmelden und Senden. Der Quellcode ist ein wenig komplex:


EventBus.subscribe( new TypeReference<Holder<Date>>(){}.getType(), new EventSubscriber<Object>() {
@Override public void onEvent( Object evt ) {
System.out.println( ((Holder)evt).value );
}
} );


EventBus.publish( new TypeReference<Holder<String>>(){}.getType(), new Holder<String>("String value") );
EventBus.publish( new TypeReference<Holder<Date>>(){}.getType(), new Holder<Date>( new Date() ) );

Jetzt wird nur noch das Datum empfangen und auf den Bildschirm kommt:

Thu Mar 26 14:28:15 CET 2009

Topics

  • Im Regelfall sind nicht alle Interessenten an allen Ereignissen interessiert.
  • Man kann nun verschiedene Ereignistypen definieren, doch wenn man etwa Strings verschicken möchte, ist es lästig, diesen String extra in in Ereignisobjekt zu verpacken.
  • Die Lösung sind Topics, also bestimmte Themen, zu denen man sich anmelden kann und zu denen man schicken kann.
  • Es ändern sich in der API zwei Dinge: Bei publish() ist der Topic anzugeben, bei subscribe() ist statt ein EventSubscriber ein EventTopicSubscriber nötig, da der Listener neben dem Event auch den Topic übergibt.

Beispiel mit Topics


EventBus.subscribe( "Error", new EventTopicSubscriber() {
@Override public void onEvent( String topic, Object evt ) { System.out.printf( "'%s' für Topic '%s'%n", evt, topic ); }
} );

EventBus.publish( "Error", "Hallo Welt" );

Liefert dann

‚Hallo Welt‘ für Topic ‚Error‘

Für mehrere Topics anmelden

  • Soll ein EventTopicSubscriber für mehrere Topics angemeldet werden, so kann man natürlich schreiben: EventTopicSubscriber ets = … EventBus.subscribe( topic1, ets ); EventBus.subscribe( topic2, ets );
  • Eine weitere subscribe()-Methode ist subscribe(java.util.regex.Pattern, EventTopicSubscriber).
    • Damit lassen sich leicht über reguläre Ausdrücke Gruppen bilden.

EventBus.subscribe( Pattern.compile( „Error|Warning“ ), new EventTopicSubscriber() { …

EventBus.publish( „Error“, „Hallo Welt“ );
EventBus.publish( „Info“, „Hallo Welt“ ); // Kommt nicht an
EventBus.publish( „Warning“, „Hallo Welt“ );

EventBus und AWT Event Dispatching Thread (EDT)

  • Setzt man in die onEvent()-Methode die Anweisung System.out.println( Thread.currentThread() ); // Thread[AWT-EventQueue-0,6,main] so findet man, dass der EventBus den Programmcode im AWT Event Thread abarbeitet.
  • Das ist natürlich gut für Aktionen, die an den Swing-Komponenten vorgenommen werden.
    • Zum Beispiel: Ein beliebiger Thread lädt Daten und möchte nach dem Laden eine Statuszeile aktualisieren. Schickt der Thread dann mit publish() ein Ereignis, wird der Programmcode vom Empfänger im EDT ausgeführt, sodass dort etwa ein setText() auf einem JLabel der Statuszeile erlaubt ist.
  • Auf der anderen Seite hat das zur Konsequenz, dass der Programmcode schnell sein muss, damit der EDT nicht zu lange blockiert wird.
  • Bei nicht-AWT-Anwendungen ist die Abarbeitung im EDT unsinnig

EventBus und SwingEventService

  • Der EventBus setzt den Programmcode standardmäßig in den EDT, kann ihn aber auch von einem anderen Thread abarbeiten lassen.
  • System.out.println( EventBus.getGlobalEventService() ); // org.bushe.swing.event.SwingEventService@173a10f
  • Standardmäßig nutzt EventBus also intern eine SwingEventService-Objekt.
  • Alternativ kann man schreiben: SwingEventService eventing = new SwingEventService(); eventing.subscribe( Object.class, new EventSubscriber() { @Override public void onEvent( Object evt ) { System.out.println( evt ); } } ); eventing.publish( „Hallo“ );

SwingEventService und ThreadSafeEventService

  • Neben dem SwingEventService gibt es den ThreadSafeEventService für eine Abarbeitung, die nicht im EDT stattfindet.
    • Beide Implementieren die Schnittstelle EventService. (Genaugenommen ist SwingEventService eine Unterklasse von ThreadSafeEventService.)
  • Man schreibt dann: EventService eventing = new ThreadSafeEventService(); eventing.subsribe(…); eventing.publish(…);

EventServiceLocator (1)

  • Den EventBus kann man nun so umstellen, dass er standardmäßig den ThreadSafeEventService nutzt.
    • Dazu wird intern ein EventServiceLocator eingesetzt.

    System.out.println( EventBus.getGlobalEventService() ); // org.bushe.swing.event.SwingEventService System.out.println( EventServiceLocator.getEventBusService() ); // org.bushe.swing.event.SwingEventService System.out.println( EventServiceLocator.getSwingEventService() ); // org.bushe.swing.event.SwingEventService

  • Der EventServiceLocator verwaltet also zwei unterschiedliche Event-Services.

EventServiceLocator (2)

try { EventServiceLocator.setEventService(EventServiceLocator.SERVICE_NAME_EVENT_BUS, new ThreadSafeEventService()); } catch ( EventServiceExistsException e ) { e.printStackTrace(); }

System.out.println( EventBus.getGlobalEventService() ); // org.bushe.swing.event.ThreadSafeEventService System.out.println( EventServiceLocator.getEventBusService() ); // org.bushe.swing.event.ThreadSafeEventService System.out.println( EventServiceLocator.getSwingEventService() ); // org.bushe.swing.event.SwingEventService

Achtung: Das muss an den Anfang bevor ein Event je den Bus sieht!

EventServiceLocator (3)

  • Wenn man nun Ereignisse über einen „normalen“ Thread bearbeitet haben möchte, schreibt man wie üblich EventBus.publish()/subscribe().
  • Sollen die Eventanweisungen in den EDT, schreibt man EventServiceLocator.getSwingEventService().publish()/subscribe().

Hängende Referenzen bei Listenern

  • Ein häufiges Problem bei Listenern insbesondere bei Swing-Anwendungen sind angemeldete Listener, für die der Interessent aber schon weg ist. Ein Szenario:
    • Ein Textfeld einer Maske meldet eine Listener an, um bei Modelländerungen die Daten darstellen zu können.
    • Das Model speichert den Listener und indirekt auch eine Referenz auf das Textfeld.
    • Die Maske verschwindet, somit auch der Interessent für Modelländerungen.
    • Da aber das Model den Listener und indirekt das Textfeld referenziert, kann der GC das Textfeld gar nicht freigeben.
    • Daher müssen Listener immer abgemeldet werden, oder…?

EventBus und WeakReference (1)

  • Damit Listener bei nicht mehr aktiven Horchern automatisch verschwinden, kann man WeakReferences einsetzen.
  • Eine WeakReference ist wie ein Proxy, der ein anderes Objekt ummantelt. Ist die WeakReference die einzige Referenz, die sich für das Objekt interessiert, so kann sie beim nächsten GC das Objekt wegräumen. Der Proxy wird dann ebenfalls nicht mehr benutzt.
  • Standardmäßig mantelt die EventBus.subscribe(XXX, EventSubscriber)-Methoden den EventSubscriber in eine WeakReference.
    • Wenn es also keinen starken Verweis auf den EventSubscriber mehr von außen gibt, wird der EventBus diesen Listener automatisch abmelden.

EventBus und WeakReference (2)


public class First
{
First()
{
new Observer();
}

public static void main( String args[] )
{
new First();
// System.gc();
EventBus.publish( "Hallo Welt" );
}
}

EventBus und WeakReference (3)

  • Der Konstruktor erzeugt einen Observer, der aber nicht referenziert wird. Nach dem der Konstruktor abgearbeitet wurde, ist das Exemplar Freiwild für den GC.
  • Wenn in main() System.gc() aufgerufen wird, wird aufgeräumt. Damit werden die WeakReferences entsort also auch der Listener beim EventBus abgemeldet.
  • Ist das System.gc() raus, steht immer noch „Hallo“, weil das Objekt noch da ist.
  • Soll EventBus keinen WeakReference-Behälter um den Listener bauen, so nutzt man subscribeStrongly(XXX, EventSubscriber) bzw. subscribeExactlyStrongly(XXX, EventSubscriber).

Was fehlt noch?

  • EventBus kann die Listener aufzählen
  • EventBus kann Veto
  • Listener können auch über Annotationen angemeldet werden
  • Timer können Events überwachen
  • Events können gechached werden, sodass spätere Anmelder die Events auch bekommen

Seminar-Werbung. Diese Weiterbildungen sind neu bei tutego

Buchkritik: Apache Geronimo, Handbuch für den Java-Applikationsserver

Frank Pientka. dpunkt-Verlag. ISBN 978-3-89864-517-1. 01/2009. 330 Seiten

Der zertifizierte Java EE 5 App-Server Geronimo steht immer ein wenig im Schatten der beiden „Großen“: JBoss und GlassFish. Dass dafür kein Anlass besteht, zeigt sich schnell durch die Möglichkeiten von Geronimo und die Zuneigung von IBM. Wer sich also für Geronimo entschieden hat und ein deutschsprachiges Buch sucht, der wird an Frank Pientkas Buch nicht vorbeikommen, denn es ist neben dem weniger aktuellen „Geronimo schnell + kompakt“ das einzige. Wer die englische Sprache bevorzugt, hat die Auswahl zwischen drei weiteren Büchern. Pientka stellt auf 250 Seiten die zentralen Aspekte von Geronimo vor (plus 50 Seiten Anhang). Für Java EE 5-Einsteiger gibt es ebenfalls ein Kapitel. Zusammenfassend lässt sich sagen: Das Buch behandelt alle relevanten Aspekte und bietet viele Verweise auf weiterführende Webseiten. Das Geronimo-Buch verirrt sich glücklicherweise nicht in Geronimo-Internas wie zum Beispiel „JBoss Administration and Development“ aus dem Jahr 2002 – einem JBoss-Buch, das mit UML-Diagrammen vollgestopft ist Admin-Informationen mit Internas vermischt. Des Weiteren hält sich Pientka an den Java EE 5-Standard. Containerspezifische Java EE-Erweiterungen werden nicht besprochen. Dabei bieten gerade die Apache-Implementierungen weitere Möglichkeiten, etwa JPA-Tuning durch spezielle OpenJPA-Annotationen, JMS-Erweiterungen von ActiveMQ für hierarchische Topics oder verschlüsselte Verbindung beim JNDI-Kontext, also Aspekte, die über den Standard hinausgehen, die Geronimo möglich macht. Wie etwa Hibernate statt OpenJPA als JPA-Provider konfiguriert wird, steht nicht im Buch, vielleicht auch, weil dieses Thema bislang im Internet nur spärlich dokumentiert ist. Die eine oder andere Schwäche findet sich in den Quellcodes. Zeilen wie catch (java.lang.Exception e) und mitunter Zeilenumbrüche, die an den Obfuscated Content erinnern, sind nicht unbedingt schön. Einige Aussagen sind missverständlich, etwa „Geronimo selbst verwendet […] sehr populäre Ajax-Bibliotheken JSON […]“ oder dass Dojo und DWR Teile des Java EE-Standards sind. Wünschen wir uns, dass der Autor das Buch schnell aktualisiert damit es zukünftig Geronimo 2.1 statt Geronimo 2.0, „IIS-Versionen 6 und 7“ statt „auch wenn die aktuellsten IIS-Versionen 5 und 6“, MyFaces statt myFaces, StAX statt STAX heißt und SOAP nicht mehr „Simple Object Access Protocol“ genannt wird. Diese sprachlichen Kleinigkeiten werden sicherlich bereits in der kommenden Auflage zu Java EE 6 behoben sein. Fehler sollten auf http://www.dpunkt.de/buecher/2827.html dokumentiert werden.

Thema der Woche: Vernünftige Oberflächen, UI-Guidelines

Dass es unsinnige und schwer verständliche Gui-Oberflächen geht ist spätestens dann klar, wenn man sich folgendes Beispiel anschaut:

Besorge die UI-Guidelines und blättere

Lese anschließend

Auffälligkeiten von SmartGWT 1.0b2 und Ext-GWT 1.2.3. nach einer Stunde spielen

  • Die Container und Layout-API sehen ein wenig anders aus. Bei SmartGWT gibt es eine Klasse Layout (und Unterklassen wie VLayout), die eigentlich Container mit einem speziellen assoziierten Layoutmechanismus sind. So heißt es dann auch layout.addMember(…) und das ist gewöhnungsbedürftig. Da gefällt mir Ext-GWT besser, wo wie bei AWT/Swing den Layout-Manager auf einem Container setzt. Hier wird also bei Ext-GWT das übliche Strategie-Muster eingesetzt.
  • Die Optik von Ext-GWT (etwa bei Menüs) ist in meinen Augen deutlich besser. Es gibt viele kleine Fehler in der Darstellung, etwa Ein-Pixel freie Linien.
  • Ext-GWT bietet bessere Unterstützung für Formulare, was etwa das automatische Ein-/Ausfalten von Details angeht.
  • SmartGWT bietet vertikale Tabs und eine Integration vom Google Kalander.
  • Das Binding funktioniert bei beiden völlig anders. SmartGWT erwartet spezielle Binding-Komponenten, also etwa DataSourceTextField statt TextItem (ja, warum das nun nicht DataSourceTextItem heißt, ….). Wenn später Quellcode umbaut wird, muss man die Komponenten ändern und wenn eine angepasste Unterklasse etwa von TextItem erbt, muss das auch anpasst werde. Das Design ist in meinen Augen nicht optimal. Besser macht es Ext-GW; hier bleibt man bei den Standardkomponenten und setzt diese später zu einer Gruppe (FormBinding) zusammen.
  • Ext-GWT bietet eine prima XTemplate-Klasse, in der dann Platzhalter definiert werden können, etwa {[new Number(values.change).toFixed(2)]}, die später über das Binding ersetzt werden.
  • Bei SmartGWT lässt sich nicht jede Komponente in einen DynamicForm setzen. Bei der RTF-Komponente RichTextEditor (ein VLayout) geht das zum Beispiel nicht. Dafür gibt es noch mal den Wrapper RichTextItem (ein FormItem). Das ist verwirrend.
  • Ohne Anpassungen beim SmartGWT ist der Font rechts einer Checkbox ein andere als Links von einem Textfeld.Und Warum muss bei TextItem immer standardmäßig ein Doppelpunkt gesetzt werden, was dann auch noch mit einem Leerzeichen vom Text abgesetzt wird?
  • SmartGWT hat merkwürdige Klassennamen wie com.smartgwt.client.core.BaseClass oder IButton (und eine Button-Klasse gibt es auch noch).
  • SmartGWT-Methoden mit den Namen addItem(), addMember(), addChild() und addPeer() tragen nicht zur Übersichtlichkeit beim Hinzufügen von Komponenten be

Fazit von einer Std. spielen und API-blättern: Ext-GWT erscheint mit vom Design durchdachter und professioneller. Die SmartGWT API wirkt an vielen Stellen unverständlich und überfachtet. Ein Beispiel:

  • void setAttribute(java.lang.String attribute, boolean value)
  • void setAttribute(java.lang.String attribute, java.lang.Boolean value)
  • void setAttribute(java.lang.String attribute, DataClass value)
  • void setAttribute(java.lang.String attribute, DataClass[] value)
  • void setAttribute(java.lang.String attribute, java.util.Date value)
  • void setAttribute(java.lang.String attribute, double value)
  • void setAttribute(java.lang.String attribute, int value)
  • void setAttribute(java.lang.String attribute, int[] value)
  • void setAttribute(java.lang.String attribute, com.google.gwt.core.client.JavaScriptObject value)
  • void setAttribute(java.lang.String attribute, java.util.Map value)
  • void setAttribute(java.lang.String attribute, java.lang.String value)
  • void setAttribute(java.lang.String attribute, java.lang.String[] value)
  • void setAttribute(java.lang.String attribute, ValueEnum[] value)

Mit Ext-GWT macht mir die Entwicklung mehr Spaß. Bei der API sind auch viel weniger Klassen/Schnittstellen im Spiel, obwohl die API viel älter ist.

SmartGWT in Eclipse nutzen

  1. Unter http://code.google.com/p/smartgwt/downloads/list lade smartgwt-1.0b2.zip und packe es aus.
  2. Setzte smartgwt.jar (und smartgwt-skins.jar falls Skinning gewünscht ist) in das lib-Verzeichnis der Web-Applikation (oder überall anderes hin, die Jar-Datei spielt ja später keine Rolle mehr) und melde die Java-Archive im Klassenpfad an.
  3. In der Modul-XML-Datei füge ein:
    <inherits name=“com.smartgwt.SmartGwt“/>
    Eintragungen für CSS in der HTML-Datei sind nicht nötig.
  4. In der onModuleLoad() kann man man etwa schreiben:
    RootPanel.get().add( new IButton(„Klick mich härter“) );
    Imports wieder generieren lassen, mit dem Präfix I gibt es keine Verwechslungen.
  5. Ideen und API aus dem http://www.smartclient.com/smartgwt/showcase/ und http://www.smartclient.com/smartgwt/javadoc/

Beispiel, um Ext GWT in Eclipse zu nutzen

Voraussetzung: http://www.tutego.com/blog/javainsel/2008/05/gwt-beispiel-in-eclipse.html

  1. Lade unter http://extjs.com/products/gxt/download.php das Ext GWT 1.2.3 SDK http://extjs.com/products/gxt/download.php?dl=gxt123 und entpacke es.
  2. Setzte gxt.jar in das WebContent/WEB-INF/lib Verzeichnis (oder überall anderes hin, die Jar-Datei spielt später keine Rolle mehr). Füge das Java-Archiv zum Klassenpfad hinzu (Java Build Path > Add)
  3. Die Host-Page im public-Ordner bekommt einen Verweis auf das Sytesheet. Setzte unter <head>:
    <link rel=“stylesheet“ type=“text/css“ href=“css/ext-all.css“ />
  4. Im public-Verzeichnis gibt es ebenfalls die Modul-XML Datei. Füge hinzu:
    <inherits name=’com.extjs.gxt.ui.GXT’/>
  5. In onModuleLoad() kann man nun ein Demoprogramm schreiben, was eine Ext GWT Komponente nutzt:
    RootPanel.get().add( new DatePicker() );
    Imports wieder automatisch generieren lassen. Aufpassen, dass man bei Mehrdeutigkeiten die korrekten import-Anweisungen generiert werden. So gibt es Window zum Beispiel zweimal.
  6. Die API-Doku http://extjs.com/deploy/gxtdocs/ und die Beispiele vom ShowCase http://extjs.com/explorer/#overview zeigen den Gebrauch der API.

Java Web App Deployment Advice für JavaSE 6u10

Seit dem Update u10 von Java 6 ist eine neue Möglichkeit hinzukommen, Java-Applets und Web-Start Anwendungen in HTML zu deklarieren. Statt sich wie bisher mit <applet>, <object> Tags rumzuärgern, oder einen Konverter über die HTML-Datei drüber laufen zu lassen, kann man eine JavaScript Biblitothek von Sun verwenden. Die Technik stellt http://java.sun.com/javase/6/docs/technotes/guides/jweb/deployment_advice.html vor. Es wird dann:

<script src=“[…]/deploy.js“>
Deploy.applet(„app.jar“,“com.bla.App“,“1.5+“);
</script>

Java 7 und Named Capturing Group

Hatte man bei reguläre Ausdrücken und Gruppen auf die Gruppen über eine Index zugreifen müssen, so kann man dies in Java 7 auch über einen Namen tun; das ganze nennt sich dann named capturing group:

  String pStr = "0x(?<bytes>\\p{XDigit}{1,4})\\s++u\\+(?<char>\\p{XDigit}{4})(?:\\s++)?";
    Matcher m = Pattern.compile(pStr).matcher(INPUTTEXT);
    if (m.matches()) {
        int bs = Integer.valueOf(m.group("bytes"), 16);
        int c =  Integer.valueOf(m.group("char"), 16);
        System.out.printf("[%x] -> [%04x]%n", bs, c);
    }

Der Blog-Eintrag http://blogs.sun.com/xuemingshen/entry/named_capturing_group_in_jdk7 gibt es in paar mehr Infos.

Thema der Woche: OSGi

Zentrale Merkmale der Java-basierten OSGi-Service-Plattform sind das dynamische Einführen, Aktualisieren und Entfernen von Service-Anwendungen zur Laufzeit. Lese das Tutorial http://www.theserverside.com/tt/articles/content/OSGiforBeginners/article.html und führe die Beispiele praktisch durch. (Das mit JSR 277: Java Module System bitte vergessen, denn das ist tot.) Lese anschließend http://en.wikipedia.org/wiki/OSGi#OSGi_Tutorial und finde einige Unterschieden zwischen http://en.wikipedia.org/wiki/Knopflerfish, http://en.wikipedia.org/wiki/Apache_Felix und http://en.wikipedia.org/wiki/Equinox_OSGi.

Thema der Woche: JUnit 4.x

Dass JUnit 4 auf Annotationen baut, ist bekannt (Kurzeinführung). Weniger bekannt sind die anderen Features, die es zu Erarbeiten geht:

  • Überfliege die Neuerungen http://junit.sourceforge.net/README.html
  • Was ergibt assertEquals( 1, new Long(1) );?
  • Was macht @RunWith?
  • Wie stellt man Filters und Sorters ein? Wozu sind sie nützlich und was steckt im Paket org.junit.runner.manipulation?
  • Was ist und wie setzt assumeThat() sie um? Was ist das Hamcrest-Projekt und was für Hamcrest Erweiterungen gibt es?
  • Was ist eine Theorie?
  • Wie schreibt man parametrisierte Tests?