Java 8 Syntax-Migration mit Eclipse

Seit der Version Eclipse 4.4 (bzw. Eclipse 4.3 mit Java 8-Erweiterung) integriert die IDE einen Code-Transformator, der Klassen-Implementierung von funktionalen Schnittellen in Lambda-Ausdrücke verkürzen kann. Diese Transformationen ist über die Quick-Fix/Quick-Assist möglich.

Eclipse_ConvertToLambda

Leider kann diese Umsetzung (bisher) nicht für ein ganzes Projekt erfolgen, und keine umfangreiche Code-Basis komplett und automatisch auf die neuen Lambda-Ausdrücke gebracht werden.

Java 8 Syntax-Migration mit NetBeans

Die aktuelle NetBeans IDE bringt einen Code-Transformer mit, der elegant die Code-Basis durchsucht und Transformationen automatisch durchführt. Das Menü Refactor bietet den Unterpunkt Inspect and Transform…, der zu einem Dialog führt:

NB_InspectAndTransform

Unter Manage… öffnet sich ein weiter Dialog, bei dem JDK Migration Support aktiviert ist und einige Änderungen voreingestellt sind, neu für Java 8 ist Covert to Lambda or Method References. Auch die Transformationen in die neue Java 7-Syntax sind voreingestellt, aktiviert werden kann: Can use Diamond, Convert to try-with-resources, Join catch sections using mulitcatch, Use specific catch und Use switch over Strings when possible.

NB_InspectAndTransform2

Wer neu Programmcode mit NetBeans schreibt wird gleich auf die neue Syntax hingewiesen. Vervollständigungen nutzen ganz natürlich zum Beispiel den Diamond-Operator.

Metadata space in JDK 8 HotSpot JVM

Wenn es um Java geht, müssen wir immer unterscheiden, ob es um die Sprache selbst geht, um die Bibliotheken, um die JVM oder um die Implementierung von Oracle, die das JDK darstellt. Eine zentrale Neuerung in der Version 8 der HotSpot JVM ist der Umgang bei der internen Repräsentation von Klassen und Metadaten; die Daten landen nicht mehr auf dem Java-Heap, sondern im nativen Speicher, der Metaspace heißt. Vorher gehörte ein java.lang.OutOfMemoryError: PermGen space zu bei großen Anwendungen zum Alltag[1], das Problem ist (im Prinzip) Vergangenheit, es gibt kein Perm-Space mehr in der JDK 8 JVM; die Oracle JRockit und JVM von IBM hatten übrigens immer Metaspace. Der Metaspace-Speicherbedarf kann mit dem Schalter MaxMetaspaceSize begrenzt werden, ein Übertritt führt zur java.lang.OutOfMemoryError: Metadata space. Eine Begrenzung ist nicht verkehrt, das Ergebnis unter Java 7 und Java 8 aber das gleiche, ein OutOfMemoryError.


[1] http://stackoverflow.com/questions/88235/dealing-with-java-lang-outofmemoryerror-permgen-space-error

Official Eclipse Support for Java 8

So ist zu lesen unter https://dev.eclipse.org/mhonarc/lists/eclipse.org-committers/msg00948.html:

The Eclipse top-level project is very proud to announce official support for Java 8. Starting with I20140318-0830 all Luna (4.4) builds contain the Eclipse support for Java™ 8. For Kepler SR2 (4.3.2) a feature patch is available. For future builds visit our downloads page.
The Java™ 8 support contains the following:
– Eclipse compiler implements all the new Java™ 8 language enhancements.
– Significant features, like Search and Refactoring, have been updated to support Java™ 8.
– Quick Assist and Clean Up to migrate anonymous class creations to lambda expressions and back.
– New formatter options for lambdas.
Note that PDE API Tools has not yet adopted the new language constructs. This will be completed in the final Luna release.
Big thanks to everyone who worked on this effort!

Java 8, es ist geschafft

Heute hat Oracle Java 8 freigegeben, es ist vollbracht. Nach langer Verzögerung können wir uns auf Lambda-Ausdrücke, einer neuen Date-Time-API und einer chicen Stream-API freuen. Auch NetBeans 8 ist mit am Start.

Die Java Insel wird in den beiden Bänden umfassend auf Java 8 eingehen, die Bücher werden in ca. 1,5 Monaten in den Buchhandlungen ausliegen und als eBook verfügbar sein. Mit den Ergänzungen bin ich komplett durch, auch das Kapitel über die Date-Time-API war nicht so übel wie gedacht, wobei mich die Typen und Hierarchien schwindlig machen machen wir auch bei den FX-Properties. Insgesamt habe ich beim Schreiben und Ausprobieren einen tiefen Eindruck in Java 8 bekommen und meine interne tutego Schulungssoftware auf Java 8 gebracht. Das passt soweit und ist rund. Ätzend ist, dass Optional nicht serialisierbar ist und bei GWT eine Sonderbehandlung braucht. Auch die Date-Time-Typen sind noch zu neu, als dass sie bei GWT, XStream, JPA berücksichtigt werden.

Java does not suck, ABER …

Java löst bei eigenen Menschen tiefere Aggressionen aus, die dann nur mit 5 Stunden Katzenvideos zu besänftigen sind. In den Tenor will ich nicht einsteigen, da ich Java an sich geil finde und die meisten Kritiken nicht teile: langsam, nicht wirklich plattformunabhängig, GC kommt zur Unzeit, geprüfte/ungeprüfte Ausnahmen, kein private protected, kein Sprachkonstrukt für Properties, keine überladene Operatoren, nicht dynamisch genug, Swing ist langsam, kein Modulsystem, Sicherheitsprobleme, …

Dafür sind es andere (kleinere) Dinge, die mich nerven:

  • Der Java-Bibliothek merkt man das Alter an. Vieles ist damals einfach in den “Container” java.util gewandert, und was warum gibt es eigentlich System und Runtime? Von Markierungsschnittstellen Serializable und RandomAccess kommen wir auch nicht mehr weg, der Vorteil ist aber, dass ein instanceof-Test billig ist. Collections ist ein Sammelsurium von Methoden rund um Collection-Typen. Warum wurden die Methoden nicht auch bei den Collection/List-Objekten festgemacht? Ein List#sort(…) wurde ja mittlerweile nachgereicht.
  • Wir haben für die gleiche Aufgabe gleich mehrere Bibliotheken in der der Java SE. Es gibt drei Gui-Komponentenbibliotheken (AWT, Swing, JavaFX), zwei Datei-APIs (java.io.File und java.nio mit Files, Path, Paths, …), zwei Datum-Zeit-APIs (Date/Calendar und java.time in Java 8).  Neueinsteiger in Projekten werden bei Datum/Zeit vermutliche eine wilde Mischung aus Date/Calendar, Joda-Time und bald Java 8 Date-Time-API finden.
  • Immer mehrere Logging-Frameworks im Projekt und folglich unterschiedliche Konfigurationen. Als es java.util.logging (JUL) noch nicht gab, war log4j quasi Standard. Dann kam JUL, log4j wolle man vereinigen, also kam Meta-Logging wie Commons Logging, später SL4J. Dann wurde es ruhig um log4j, neue Produkte kamen, wie logback. Jetzt startet Log4j 2 wieder durch …
  • Die Unterscheidung zwischen primitiven Datentypen und Wrapper-Typen wird immer irrer, schaut man auf Java 8 in das java.util.function-Paket: BooleanSupplier, DoubleBinaryOperator, DoubleConsumer, DoubleFunction<R>, DoublePredicate, DoubleSupplier, DoubleToIntFunction, DoubleToLongFunction, DoubleUnaryOperator, IntBinaryOperator, IntConsumer, IntFunction<R>, IntPredicate, IntSupplier, IntToDoubleFunction, IntToLongFunction, IntUnaryOperator, LongBinaryOperator, LongConsumer, LongFunction<R>, LongPredicate, LongSupplier, LongToDoubleFunction, LongToIntFunction, LongUnaryOperator, ObjDoubleConsumer<T>, ObjIntConsumer<T>, ObjLongConsumer<T>, ToDoubleBiFunction<T,U>, ToDoubleFunction<T>, ToIntBiFunction<T,U>, ToIntFunction<T>, ToLongBiFunction<T,U> , ToLongFunction<T> (OMG!) Ähnliches in javafx.beans.property auch noch mal.
  • Oracle-Webseiten verschwinden, Sun-Seiten wurden nicht übertragen.  Für die kommende Version vom Buch muss ich zwangsläufig alle Links prüfen, viele leiten auf übergeordnete Seiten weiter und sind verschwunden. Bei einer Seite wie http://docs.oracle.com/javase/7/docs/technotes/tools/ erwartet man, dass man 7 durch 8 ersetzen kann und dann kommt man irgendwie bei der Doku von Java 8 aus, oder? Ist aber nicht so …
  • Bug-Base-IDs und Links stimmen oft nicht, Bug gibt es angeblich nicht.
  • toString()-Methoden sind i.d.R. Debug-Methoden, warum implementiert ein Array –Objekt kein vernünftiges toString()?
  • GlassFish ist nicht mehr kommerziell supported wobei es die RI ist. Wie soll man Kunden dann für so ein tolles Produkt begeistern können?
  • Kein standardisiertes Web-Framework bis aus JSF, das reicht nicht. In der Microsoft-Welt hat man erkannt, dass man auch ein (anderes) MVC-Framework braucht, dort gib es ASP.NET MVC Framework und das klassische ASP.
  • Zwei Compiler; der Standard-Compiler und der Eclipse-Compiler (EJC) sind auf unterschiedlichem Niveau und gibt es neue Java-Version, bauen die Eclipse-Macher alles nach. Das dauert und die Compiler sind nicht identisch. Compiler werden immer komplexer.
  • Unklare Zukunft von NetBeans. Bei NB gibt es nach der kommenden Version NB 8.0 (erwartet April 2014) überhaupt keine Zukunftsaussagen. Viele Entwickler sind aus NB abgezogen worden, ob es überhaupt weiter geht und in welchem Tempo ist offen.
  • Unklare Aussage über die Zukunft von Bibliotheken. Wie wird sich GWT weiter entwickeln? Was ist mit anderen Projekten? Oftmals wird das Intervall von Code-Änderungen immer größer, die Projektseite erfährt keine Updates und das Projekt schläft ein. Wie viele UML-Tools sind schon gekommen und gegangen?
  • Oracle hat in Java 7-Updates 51 die Sicherheitsrichtlinien für belegbare Ports verschärft, mit der Konsequenz dass plötzlich Derby nicht mehr läuft und somit alle Standard-Tutorials für JDBC/JPA schon am Anfang eine Hürde nehmen müssen: “The default socket permissions assigned to all code including untrusted code have been changed in this release. Previously, all code was able to bind any socket type to any port number greater than or equal to 1024. It is still possible to bind sockets to the ephemeral port range on each system. The exact range of ephemeral ports varies from one operating system to another, but it is typically in the high range (such as from 49152 to 65535). The new restriction is that binding sockets outside of the ephemeral range now requires an explicit permission in the system security policy..”
  • Suche in Javadoc ist immer noch nicht möglich, ein wenig JavaScript könnte nicht schaden.

Was nervt euch?

Neue Version vom Apache JSPWiki

Das Apache JSPWiki is ein Wiki-System auf der Basis einfacher Java-Technologien Servlets und JSP. Apache JSPWiki gibt es nun in der Version 2.10, Details unter http://jspwiki.apache.org/.

Some of its features include:

  • WikiMarkup/Structured Text
  • File attachments
  • Templates support
  • Data storage through your choice of two WikiPage Providers, with the capability to create and plug in new ones
  • Security: fine grained control over authorization and authentication, yet simple to configure
  • Easy plugin interface
  • UTF-8 support
  • JSP-based
  • Easy-ish installation
  • Page locking to prevent editing conflicts
  • Support for Multiple Wikis

Doch wohl keine Collection-Literale in Java 9

So ist aktuell Stand der Dinge: http://mail.openjdk.java.net/pipermail/lambda-dev/2014-March/011938.html in Referenz zu http://openjdk.java.net/jeps/186:

Just to close the loop here, we've reached the conclusion that we will 
not be pursuing collection literals as a language feature right now, but 
instead proceeding in the short term with a library-based proposal that 
is similar to what Stephen has described here, with a few ideas from 
Guava's ImmutableXxx classes.

Verzeichnisse nach Dateien iterativ durchsuchen (vor Java 7)

Bevor NIO.2 in Java 7 einen FileVisitor einführte, musste ein Verzeichnis inklusive aller Unterverzeichnisse selbst abgelaufen werden, um Dateien zu finden. Um das selbst zu realisieren helfen uns die Datenstrukturen und die list(…)-Methode von File.

Dabei sollen Dateien gefunden werden, deren Dateinamen auf regulären Ausdrücken »matchen«. Ein List-Objekt speichert bereits gefundene Dateien, und ein Stack merkt sich via Tiefensuche das aktuelle Verzeichnis, in dem der Algorithmus gerade steht. Anders als bei DeleteTree nutzt diese Implementierung keine rekursiven Methodenaufrufe:

import java.io.*;
import java.util.*;
import java.util.regex.Pattern;

public class FileFinder {
  public static List<File> find( String start, String extensionPattern ) {
    List<File> files = new ArrayList<>( 1024 );
    Queue<File> dirs = Collections.asLifoQueue( new LinkedList<File>() );
    File startdir = new File( start );
    Pattern p = Pattern.compile( extensionPattern, Pattern.CASE_INSENSITIVE );

    if ( startdir.isDirectory() )
      dirs.add( startdir );

    while ( dirs.size() > 0 )
      for ( File file : dirs.remove().listFiles() )
        if ( file.isDirectory() )
          dirs.add( file );
        else if ( p.matcher( file.getName() ).matches() )
          files.add( file );

    return files;
  }
}

Eine Nutzung der Utility-Methode ist einfach, wie etwa die folgenden Zeilen zeigen, um Dokumente mit den Dateiendungen .gif und .jpg zu finden:

String path = new File( System.getProperty(„user.dir“) ).getParent();

System.out.println( „Suche im Pfad: “ + path );

List<File> files = FileFinder.find( path, „(.*\\.gif$)|(.*\\.jpg$)“ );

System.out.printf( „Fand %d Datei%s.%n“,
                   files.size(), files.size() == 1 ? „“ : „en“ );

for ( File f : files )
  System.out.println( f.getAbsolutePath() );

Javadoc-Überprüfung mit DocLint

Neu in Java 8 ist eine Erweiterung des Javadoc Tools, die in den Javadoc-Kommentaren Fehler aufspürt. Es heißt DocLint. Aktiviert wird diese Prüfung mit dem Schalter –Xdoclint und es erkennt folgende Gruppen von Fehlern, die auch als Option angegeben werden können:

Gruppe

Beschreibung

accessibility

Prüft auf Probleme mit der Zugänglichkeit der Dokumentation, dass etwa Tabellen immer eine Zusammenfassung besitzen.

html

Erkennt HTML-Fehler, wie fehlende schließende spitze Klammern.

missing

Prüft auf fehlende Elemente, wenn zum Beispiel ein Kommentar fehlt, oder @return.

reference

Prüft alle Referenzen in den Javadoc-Tags, etwa bei @see oder auch ungültige Namen bei @param.

syntax

Prüft allgemeine Syntaxfehler wie nicht ausmaskierte HTML-Zeichen wie “<“, „>“ oder „&“ und nicht existierende Javadoc-Tags

Mögliche Gruppen bei Javadoc und dem DocLint Werkzeug

Zu weitere Optionen der Javadoc-Erweiterung siehe http://download.java.net/jdk8/docs/technotes/tools/windows/javadoc.html.