Mittwoch, 14. Juli 2010

Scala 2.8 und Lift 2.0

Knapp ein dreiviertel Jahr nach der letzten offiziellen Version 2.7.7 ist es heute endlich soweit: Scala 2.8 wurde veröffentlicht! Neben zahlreichen Bugfixes gibt es viele Neuerungen:
  • leichtgewichtigere, performantere Aktoren
  • Unterstützung für Continuations
  • verbesserte XML-Bibliothek
  • Überarbeitete Kollektions-Bibliothek und Array-Implementation
  • Benannte und Default-Argumente
  • Package-Objekte
  • bessere Unterstützung für (verschachtelte) Java-Annotationen
  • deutlich verbesserte Scala-Interpreter-Shell (REPL), u.a. mit Tab-Eingabevervollständigung
  • u.a.
Die Werkzeuge Sbaz und Scaladoc liegen in Version 2 vor, der Decompiler Scalap wurde an aktuelle Sprachkonstrukte angepasst. Die Scala IDE für Eclipse wurde intensiv überarbeitet, wodurch sie nun u.a. besser in die Java-Werkzeuge von Eclipse eingebunden ist.


Bereits vor zwei Wochen wurde das Scala-Web-Framework Lift 2.0 veröffentlicht. Neben der bisher schon sehr guten Ajax- und Comet-Unterstützung gibt es u.a. folgende Neuerungen:

Zum Schluss ein bisschen Werbung in eigener Sache: Wer mehr über Scala erfahren möchte, darf gerne an meinem nächsten Scala-Workshop teilnehmen, der Ende November in Köln stattfindet!

One more thing...

Dienstag, 15. Juni 2010

NetBeans 6.9 inkl. JavaFX Composer

Heute hat Oracle/Sun NetBeans 6.9 fertig gestellt und veröffentlicht. Eines der wichtigsten neuen Merkmale dürfte der nun standardmäßig integrierte JavaFX Composer sein, mit dem sich Formulare und Grafiken für JavaFX 1.3 visuell erstellen lassen:

Mal abwarten, wie sich der GUI-Editor in der Praxis bewährt. Aber die ersten Versuche sehen recht vielversprechend aus.

Im Bereich "Java EE" ist die Unterstützung für den JSR-299 (CDI) sowie für Spring 3.0 erwähnenswert. Außerdem ist der Application Server GlassFish in der Version 3.0.1 integriert.

Montag, 31. Mai 2010

JavaFX 1.3

Nur der Vollständigkeit halber... Bereits Ende letzten Monats hat Oracle/Sun JavaFX 1.3 veröffentlicht. Die wichtigsten Neuerungen sind
  • neue Controls (u.a. endlich eine ChoiceBox)
  • neue, brauchbare Layouts
  • bessere CSS-Unterstützung
  • bessere Performance und weniger Speicherverbrauch.
Beschreibungen und Zusammenfassungen der Änderungen und Neuerungen finden sich u.a. hier, hier und hier.

Wichtiger für die Akzeptanz von JavaFX ist m.E. aber, dass mit der Beta-Version von NetBeans 6.9 der JavaFX Composer mitgeliefert wird, mit dem Benutzeroberflächen (GUIs) – sowohl Masken als auch Grafiken – visuell zusammengestellt werden können.

Die Migration bestehender Java FX 1.2-Anwendungen auf die neue Version ist hier beschrieben.

Dienstag, 20. April 2010

Hibernate 3.5 mit JPA 2.0 und Envers

Einige Wochen war es ruhig in diesem Blog, aber mit der Veröffentlichung unseres aktuellen Projekts Klaas 1.0 hatten wir alle Hände voll zu tun :-)

In der Zwischenzeit wurde nach vielen Monaten der Entwicklung Ende März endlich Hibernate 3.5 fertiggestellt. Mittlerweile steht sogar schon das erste Bugfix-Release Hibernate 3.5.1 zur Verfügung.

JPA 2.0 wird nun vollständig unterstützt, und mit Envers ist eine Bibliothek zur automatischen temporalen Datenhaltung (Historisierung bzw. Versionierung) enthalten. Außerdem wurde die Abhängigkeitsverwaltung der Hibernate-Teilprojekte vereinfacht, denn aufeinander abgestimmte Versionen der Hibernate-Annotationen, des Hibernate-EntityManagers und von Envers sind nun im Hibernate-Core-JAR enthalten.

Freitag, 26. Februar 2010

Closures in JavaScript

Nachdem ich schon Beispiele für Closures (Funktionsabschlüsse) in JavaFX und Scala vorgestellt hatte, schauen wir uns dasselbe Beispiel in JavaScript (ECMAScript) an:
// closures.js

function zaehlerMitStartwert(startwert) {
return function() {
return startwert++
}
}

next1 = zaehlerMitStartwert(10)
next2 = zaehlerMitStartwert(20)

document.writeln( next1() ) // 10
document.writeln( next2() ) // 20
document.writeln( next2() ) // 21
document.writeln( next1() ) // 11

Sehr viel mehr gibt es dazu eigentlich nicht zu sagen, außer dass es
  1. wirklich so einfach ist (was auch zu Problemen führen kann)
  2. schon seit den ersten JavaScript-Versionen (und damit seit über 10 Jahren) zur Verfügung steht und
  3. im Gegensatz zu JavaFX Script und Scala dynamisch typisiert ist; zudem ist keine zusätzliche lokale Variable nötig, weil der Übergabeparameter startwert bereits eine veränderbare Variable ist. Beides ist im Hinblick auf stabile, wartbare Software nicht unbedingt als positiv zu bewerten.
Viele moderne JavaScript-Bibliotheken machen starken Gebrauch von solchen Funktionsliteralen und Closures, beispielsweise jQuery.

Dienstag, 16. Februar 2010

Hibernate/JPA, hashCode() und Eclipse

Entitäten in Hibernate/JPA haben oft einen synthetischen (technischen) Primärschlüssel, der im folgenden Beispiel als Long id implementiert wird. Sofern es keine zusätzlichen fachlichen Schlüsselkandidaten gibt, muss man die hashCode()-Methode für Hibernate/JPA so implementieren, dass sie ausschließlich mit dieser Id arbeitet. (Es gibt auf hibernate.org eine lange Diskussion zu diesem Thema, denn die "offiziell" vorgeschlagene Variante, "halb-eindeutige" Felder zu verwenden, macht in der Praxis meistens mehr Probleme als die Id-Variante.)

Damit man hashCode() (und das zwingend dazu gehörende equals()) nicht immer wieder von Hand neu schreiben muss, bietet Eclipse über Source > Generate hashCode() and equals() die Möglichkeit, die beiden Methoden mit wählbaren Attributen zu generieren. Eine Beispiel-Entität könnte dann wie folgt aussehen:
@Entity
public class Datensatz {

@Id @GeneratedValue
private Long id;

// weitere Felder, Getter, Setter, equals() etc. ...

/**
* Von Eclipse 3.5 generiert.
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((id == null) ? 0 : id.hashCode());
return result;
}
}
An sich liefert die Hashwert-Berechnung mittels Primzahlen eine gute Streuung, und der automatisch generierte Code beachtet auch, dass die Id null sein kann – nämlich bei noch nicht in der Datenbank gespeicherten (persistierten) Objekten.

Nun testen wir diese Entity-Klasse:
@Test
public void testAddToHashSet() {

Set<Datensatz> menge = new HashSet<Datensatz>();

Datensatz ds1 = new Datensatz();
Datensatz ds2 = new Datensatz();

assertTrue("Menge sollte leer sein", menge.isEmpty());

menge.add(ds1);

assertTrue("Menge sollte ein Element besitzen",
menge.size() == 1);
// ok

menge.add(ds2);

assertTrue("Menge sollte zwei Elemente besitzen",
menge.size() == 2);
// immer noch 1... Ups!?!
}
Immer, wenn man Assoziationen im Objekt-Modell aufbaut, bevor die Datensätze gespeichert sind (also z.B. bei Unit-Tests wie im obigen Beispiel), tritt das gezeigte Szenario auf. Wir haben hier zwei Objekte, die beide keine Id (=null) besitzen. Es sind aber trotzdem zwei nicht identische Objekte in separaten Speicherbereichen, die beim Persistieren entsprechend zwei Datensätze mit unterschiedlichen Primärschlüsseln (Ids) erzeugen würden. Leider kann sich das HashSet nur eines der beiden Objekte merken – und auch beim Persistieren einer Assoziation ginge so eines der Objekte verloren!

Eine Anpassung der generierten hashCode()-Methode ist denkbar einfach. Statt bei einer nicht vorhandenen Id die Zahl 0 für die Hashwert-Berechnung zu verwenden, nehmen wir den Hashwert des Objekts, der bei nicht identischen Objekten in den allermeisten Fällen unterschiedlich ist:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((id == null) ? super.hashCode() : id.hashCode());
return result;
}
Eine vergleichbare Implementierung nutze ich seit Jahren ohne Probleme, weshalb ich diese Variante pauschal für die praktikabelste halte. In Einzelfällen mögen natürlich speziellere Implementierungen sinnvoller sein.

Mittwoch, 3. Februar 2010

HTML-Accesskey mit CSS darstellen

Mit dem Standard-HTML-Attribut accesskey lassen sich Tastaturkürzel (Shortcuts) definieren, mit denen man den Eingabefokus auf die zugehörigen Eingabeelemente setzen kann:
<label for="nachname" accesskey="n">Nachname:</label>
<input id="nachname" type="text">
Mit welcher Tastenkombination der Fokus gesetzt wird, ist browser- und systemabhängig. Obiges Kürzel aktiviert man im IE/Win mit Alt+N, im Firefox/Win mit Shift+Alt+N, im Firefox/Mac mit Ctrl+N, in Safari/Mac mit Ctrl+Alt+N...

Natürlich sollte man dem Anwender auch anzeigen, dass Tastaturkürzel vorhanden sind. Man kann diese Information zwar noch einmal statisch in den HTML-Quelltext schreiben (zusätzlich zum accesskey-Attribut). Mit einer einfachen CSS2-Regel kann man aber auf solche redundanten Angaben verzichten und die Kürzel an allen label-Elementen darstellen lassen, bei denen accesskey gesetzt ist:

label[accesskey]:after {
content: " [" attr(accesskey) "]";
text-transform: uppercase;
color: #999999;
font-size: x-small;
}

Die CSS-Regel basiert vor allem auf einem Attribut-Selektor und einem Pseudo-Element. Dadurch wird nach (:after) jedem label-Element, bei dem das accesskey-Attribut vorhanden ist, der Wert des Attributs in Großschreibung (uppercase) in den Dokument-Inhalt (content) eingefügt:



An sich sind diese Techniken recht alt, die entsprechenden Standards wurden schon vor Jahren offiziell verabschiedet (die HTML 4.01-Spezifikation ist über 10 Jahre alt, CSS 2 ebenso). Was macht dieses Thema wieder aktuell?

Google hat vor kurzem angekündigt, ab dem 1. März dieses Jahres ältere Browser-Versionen und insbesondere den Internet Explorer 6 (IE6) nicht mehr in seinen Web-Anwendungen zu unterstützen.
Dieser – eigentlich längst überfällige – Schritt dürfte auch andere Anbieter dazu bewegen, neuere IE-Versionen (oder Alternativen wie Firefox) vorauszusetzen. Und dann könnten auch endlich IE-Nutzer von Web-Standards wie den Attribut-Selektoren profitieren, die der IE6 leider seit Jahren ignoriert.