Offtopic: Flow, statische Typprüfung für JavaScript

Wer viel mit JavaScript arbeitet, wird sich über eine Lösung von FaceBook freuen, die JS-Code statisch prüft, um Typfehler zu finden. Mehr unter ttps://code.prod.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-javascript/ und auf der Hauptseite http://flowtype.org/.

Ein Beispiel:

/* @flow */

function foo(x) {
  return x * 10;
}

foo('Hello, world!');

Führt zu nach dem Aufruf vom Kommandozeilenprogramm flow zum Fehler:

01_HelloWorld/hello.js:7:5,17: string This type is incompatible with 01_HelloWorld/hello.js:4:10,13: number

GWT 2.7 final

Aus den Release-Notes: http://www.gwtproject.org/release-notes.html#Release_Notes_2_7_0 (nur Fixes, Neuerungen in den RC erklärt):

Highlights
  • Super Dev Mode is now the default. DevMode automatically starts Super Dev Mode and reloading a web page automatically runs the compiler when necessary. (The -noSuperDevMode flag may be used to revert to the old behavior.)

  • Compiling in Super Dev Mode is much faster after the first compile.

  • Experimental support for GSS, also known as Closure Stylesheets. (See below.)

Known Issues
  • gwttar files are incorrect. (Fixed in the next version.)
Deprecations
  • GWT Designer doesn’t work with 2.7 and is no longer supported. (Source code is available if someone wishes to revive this project.)

  • IFrameLinker and XSLinker are deprecated because they don’t work in Super Dev Mode. However, we don’t have suitable replacements for all use cases yet. For updates and possible workarounds, see issue 8997.

Compiler changes
  • In draft mode and Super Dev Mode, all compiler optimizations are turned off for better debugging. For example, null pointers are detected sooner.

  • JSNI references no longer require fully qualified class names when this wouldn’t be necessary in Java. (For example, imports work.)

  • We’ve started implementing JS Interop annotations, which will make it much easier to use GWT with JavaScript libraries. The specification is not final and there are bugs, so production GWT apps and libraries should continue to use JSNI for now. If you wish to experiment, you can enable JS Interop using the -XjsInteropMode flag, which is available for the compiler and Super Dev Mode. (It doesn’t work with old DevMode.)

  • The experimental -XmethodNameDisplayMode flag adds a displayName property to each JavaScript function containing the name of the Java method. This makes Java method names available in browser debuggers at the expense of code size. (Also available in Super Dev Mode.)

  • Boxed JavaScript strings (created in JavaScript using new String(...)) are no longer considered equivalent to Java strings. They should be unboxed before being passed to Java.

  • Many bugfixes.

Library Changes
JDK emulation
  • Significant performance improvements in String, ArrayList, HashMap, and Exception.

  • New emulated classes: Locale, NavigableSet, and NavigableMap.

  • New emulated methods in Class, String, Exception, RuntimeException, Logger, Arrays, Collections, and Map.Entry.

  • LinkedList extends Deque and handles incorrect usage better.

Logging and Stack Traces
  • Better wrapping of exceptions thrown from JavaScript.

  • GWT apps that inherit the com.google.gwt.logging.Logging module have different default behavior for messages logged using the java.util.logging package. The new default is to log messages at level SEVEREand above to the browser’s console. PopupLogHandler and SystemHandler are no longer enabled by default.

  • FirebugLogHandler and NullLoggingPopup have been removed. ()

Experimental GSS support

The CssResource.enableGss configuration property turns on GSS support.

  • When enabled, resource files with a ‚gss‘ extension are parsed as a Closure Stylesheet.

  • When enabled, GSS can be used in a UiBinder file by setting gss=true on a ui:style tag.

  • If the CssResource.legacy configuration property is set, .css resources and ui:style tags without gss=true will first be converted to GSS and then parsed as GSS.

UiBinder
  • The ui:data tag has new attributes: mimeType and doNotEmbed.
GWT-RPC
  • The rpc.XserializeFinalFields configuration property turns on experimental support for serializing final fields.

  • LinkedHashSet may be serialized without a serialization policy.

  • deRPC is removed.

RequestFactory
  • Support overridden methods and generics better.

  • Fix support for @SkipInterfaceValidation on RequestContext methods.

Internationalization
  • Upgraded to CLDR 25.
Browser API changes
  • Updated support for typed arrays.

  • Added History.replaceItem().

  • Fixed an issue with Window.addWindowScrollHandler on Chrome.

Widgets
  • The deprecated com.google.gwt.widgets package is removed.

  • Various bugfixes and minor improvements.

Developer Tool Changes
Dev Mode
  • The -noSuperDevMode flag may be used to turn off Super Dev Mode and revert to old Dev Mode. (However, most current browsers no longer support Dev Mode plugins.)

  • The -modulePathPrefix flag may be used to move DevMode’s output to a subdirectory of the war directory.

Super Dev Mode
  • Compiling is much faster after the first compile. (Compiling is skipped altogether if no files have changed.)

  • The first compile no longer happens at startup.

  • Chrome reloads the page faster while debugging. (Sourcemap file size is reduced.)

  • The -launcherDir flag may be used to avoid running the GWT compiler before starting Super Dev Mode. When enabled, Super Dev Mode writes stub .nocache.js files that automatically recompile the GWT app before loading it. Therefore the bookmarklets aren’t needed. (This feature is automatically enabled when launched via DevMode.)

  • The -logLevel flag may be used to adjust how compile errors are reported.

  • The Dev Mode On bookmarklet dialog shows whether Super Dev Mode is turned on for each module on the page.

  • Messages logged using java.util.logging at level SEVERE and above are written to the browser console by default.

  • Fixed a startup failure caused by locked directories on Windows.

Testing
  • Better error reporting for compile errors while running tests.

  • Messages logged using java.util.logging at level SEVERE and above are written to the browser console and test output by default.

  • -Dgwt.htmlunit.debug may be used to open a JavaScript debugger window when running a test using HtmlUnit.

  • Removed RunStyleRemoteWeb and the BrowserManager tool.

  • Removed flags: -standardsMode, -nostandardsMode, -quirksMode. (GWTTestCase tests are always run in an HTML page in standards mode.)

For even more detail, see the Issue Tracker.

Endlich passt auch das Google Eclipse Plugin direkt zur neuen Version, bei meinem GWT-Projekt gab es keine Fehler, ich konnte direkt die neue Version und das Plugin nutzen.

Noch etwas:

The 2015 GWT.create conference is happening on January 22-23 in Mountain View, California and on January 27-28 in Munich, Germany.

This year’s sessions will include coverage of new functionality in upcoming versions of GWT, including Java 8 support and better interoperability with Javascript and Web Components. We will also talk about how Inbox by Gmail was built, using GWT and j2objc together to run the same code on the web and mobile devices.

JDK 9 Images sind nun modular

Das schreibt Mark Reinhold auf der Mailing-Liste: http://mail.openjdk.java.net/pipermail/jdk9-dev/2014-December/001663.html. Daraus ergeben sich eine Reihe von fundamentalen Änderungen bei den Verzeichnissen und Dateien einer JDK/JRE-Installation:

FYI, the initial changesets for JEP 220: Modular Run-Time Images [1]
were pushed just a few minutes ago.  If you build JDK 9 yourself, or if
you download the next early-access build [2] (which should be available
tomorrow), you'll see all of the changes documented in JEP 220.

To summarize (please see the JEP for details):

  - The "jre" subdirectory is no longer present in JDK images.

  - The user-editable configuration files in the "lib" subdirectory have
    been moved to the new "conf" directory.

  - The endorsed-standards override mechanism has been removed.

  - The extension mechanism has been removed.

  - rt.jar, tools.jar, and dt.jar have been removed.

  - A new URI scheme for naming stored modules, classes, and resources
    has been defined.

  - For tools that previously accessed rt.jar directly, a built-in NIO
    file-system provider has been defined to provide access to the class
    and resource files within a run-time image.

We have a few open issues to finish up, so further changes will follow
for this JEP, but none will be as disruptive as today's merge.

- Mark


[1] http://openjdk.java.net/jeps/220
[2] https://jdk9.java.net/download/

IntelliJ IDEA 14, tolle neue Features

Alle Details unter https://www.jetbrains.com/idea/whatsnew/. Auf die Schnelle:

  • built-in decompiler
  • Show Referring Objects im Debugger
  • evaluate to operator expressions im Debugger
  • infers the@NotNull, @Nullable and @Contract
  • Scala plugin comes with theChange Signature refactoring, reworked SBT integration, faster performance, brand new project configuration model, and many more
  • enhancements and new features introduced in Android Studio Beta, including support for Google Wear andTV.
  • Advanced coding assistance for Thymeleaf
  • visual diagrams forSpring Integration
  • standard Test Runner für Gradle task
  • The Scene Builder is now built into the Editor.
  • support for GlassFish 4.1, TomEE 1.7.1, WildFly 9.0.0 and tcServer 3.0.1.
  • better log viewer for Git and Mercurial
  • tools for SQL developers have been improved

Inselupdate: Wie wo was dynamisch binden

Es gibt bei Methoden von konkreten Klasse, abstrakte Klassen und Schnittstellen Unterschiede, wo der Aufruf letztendlich landet. Nehmen wir folgende Methode an:

void f( T t ) {
  t.m();
}

Fordert die Methode ein Argument vom Typ T und ruft auf dem Parameter t die Methode m() auf, so können wir folgendes festhalten:

· Ist T eine finale Klasse, so wird immer die Methode m() von T aufgerufen, da es keine Unterklassen geben kann, die m() überschreiben.

· Ist T eine nicht-finale Klasse und m() eine finale Methode, wird genau m() aufgerufen, weil kein Unterklasse m() überschreiben kann.

· Ist T eine nicht-finale Klasse und m() keine finale Methode, so könnten Unterklassen von T m() überschreiben und t.m() würde dann dynamisch die überschriebene Methode aufrufen.

· Ist T eine abstrakte Klasse und m() eine abstrakte Methode, so wird in jedem Fall eine Realisierung von m() in einer Unterklasse aufgerufen.

· Ist T eine Schnittstelle, und m() keine Default-Implementierung, so wird in jedem Fall eine Implementierung m() einer implementierenden Klasse aufgerufen.

· Ist T eine Schnittstelle, und m() eine Default-Implementierung, so kann t.m() bei der Default-Implementierung landen, oder bei einer überschriebenen Version einer implementierenden Klasse.

JBoss Tools 4.2 freigegeben

Es gibt viele Neuerungen, siehe http://tools.jboss.org/documentation/whatsnew/jbosstools/4.2.0.Final.html. Vieles dreht sich um Cordova. Die Hibernate Tools unterstützen JPA 2.1 und Hibernate 4.3. AngularJS wird erstmalig über einen Wizard zum Aufbau von HTML5-Anwendungen unterstützt sowie ist ein AngularJS Eclipse Plugin integriert. Auch node.js erkennt der JS-Editor bei der Vervollständigung, für JS-Funktionen gibt es nun auch eine API-Dokumentation aus der JS-ECMA-Spezifikation. HTML Preview ist ein WYSIWYG Plugin für HTML pages

Log4j 2.1 freigegeben

Ralph Goers hat die Freigabe von Apache Log4j 2.1 bekanntgegeben: https://mail-archives.apache.org/mod_mbox/www-announce/201410.mbox/%3CBC551B1B-6257-4DB1-B640-0858A400FC68@apache.org%3E.

Neuerungen sind unter anderem:

o LOG4J2-868:  Add ShutdownCallbackRegistry interface for customizable shutdown callback handling.
This is particularly
       useful for application servers that wish to integrate with Log4j 2. 
o LOG4J2-589:  Supported filtering on custom log levels in configuration. 
o LOG4J2-856:  Documentation: add sections on the JUL Adapter, IO Streams and NoSQL Appenders
to the Maven and Ivy page. 
o LOG4J2-848:  Add a Java lookup to provide nicely formatted runtime version information.

o LOG4J2-809:  Move reflection utility class to API's private utility classes. 
o LOG4J2-833:  Documentation: added Runtime Dependencies link to left nav-bar on site. 
o LOG4J2-816:  Documentation: added section on XInclude to user manual Configuration page.

o LOG4J2-547:  Add the Log4j IOStreams component. 
o LOG4J2-431:  Added Memory-Mapped File Appender. Thanks to Claude Mamo. 
o LOG4J2-827:  Support use of TypeConverter classes through the standard Plugin system. 
o LOG4J2-825:  Add simple validation constraint annotations for the Plugin system. 
o LOG4J2-428:  Implement a GELF layout. Thanks to Mark Paluch. 
o LOG4J2-608:  Add java.util.logging implementation based on log4j-api. See log4j-jul documentation
for more details. 
o LOG4J2-793:  Add support for custom SLF4J Markers in log4j-slf4j-impl module. 
o LOG4J2-771:  Add lookup for application main arguments. 
o LOG4J2-787:  Add lookup for JVM arguments. 

Doppelklammer-Initialisierung

Da anonyme Klassen keinen Namen haben, muss für Konstruktoren ein anderer Weg gefunden werden. Hier helfen Exemplarinitialisierungsblöcke, also Blöcke in geschweiften Klammern.

Exemplarinitialisierer gibt es ja eigentlich gar nicht im Bytecode, sondern der Compiler setzt den Programmcode automatisch in jeden Konstruktor. Obwohl anonyme Klassen keinen direkten Konstruktor haben können, gelangt doch über den Exemplarinitialisierer Programmcode in den Konstruktor der Bytecode-Datei.

Dazu ein Beispiel: Die anonyme Klasse ist eine Unterklasse von Point und initialisiert im Konstruktor einen Punkt mit Zufallskoordinaten. Aus diesem speziellen Punkt-Objekt lesen wir dann die Koordinaten wieder aus:

java.awt.Point p = new java.awt.Point() {

{

x = (int)(Math.random() * 1000); y = (int)(Math.random() * 1000);

}

};

System.out.println( p.getLocation() ); // java.awt.Point[…

System.out.println( new java.awt.Point( -1, 0 ) {{

y = (int)(Math.random() * 1000);

}}.getLocation() ); // java.awt.Point[x=-1,y=…]

Sprachlichkeit

Wegen der beiden geschweiften Klammen heißt diese Variante auch Doppelklammer-Initialisierung (engl. Double Brace Initialization).

Die Doppelklammer-Initialisierung ist kompakt, wenn etwas Datenstrukturen oder hierarchische Objekte initialisiert werden sollen.

Beispiel *

Im Folgenden Beispiel erwartet appendText(…) ein Objekt vom Typ HashMap, was durch den Trick direkt initialisiert wird:

String s = new DateTimeFormatterBuilder()

.appendText( ChronoField.AMPM_OF_DAY,

new HashMap<Long, String>() {{ put(0L, „früh“);put(1L,“spät“ ); }} )

.toFormatter().format( LocalTime.now() );

System.out.println( s );

Im nächsten Beispiel bauen wir eine geschachtelte Map, das ist ein Assoziativspeicher, der wieder einen anderen Assoziativspeicher enthält:

Map<String,Object> map = new HashMap<String,Object>() {{

put( „name“, „Chris“ );

put( „address“, new HashMap<String,Object>() {{

put( „street“, „Feenallee 1“ );

put( „city“, „Elefenberg“ );

}} );

}};

Warnung

Die Doppelklammerinitialisierung ist nicht ganz „billig“, da eine Unterklasse aufgebaut wird, also neuer Bytecode generiert wird. Zudem hält die innere Klasse eine Referenz auf die äußere Klasse fest. Des Weiteren kann es Probleme mit equals(…) geben, da wir mit der Doppelklammerinitialisierung eine Unterklasse schaffen, die vielleicht mit equals(…) nicht mehr gültig vergleichen werden kann, denn die Class-Objekte sind jetzt nicht mehr identisch. Das spricht in der Summe eher gegen diese Konstruktion.

Sich selbst mit this übergeben

Möchte sich ein Objekt A einem anderen Objekt B mitteilen, damit B das andere Objekt A „kennt“, so funktioniert das gut mit der this-Referenz. Demonstrieren wir das an einem „Ich bin dein Vater“-Beispiel: Zwei Klasen Luke und Darth repräsentieren zwei Personen, wobei Luke ein Attribut dad für seinen Vater hat:

LukeAndDarth.java, Teil 1
class Luke {
  Darth dad;
}

class Darth {
  void revealTruthTo( Luke son ) {
    son.dad = this;
  }
}

Spannend ist die Methode revealTruthTo(Luke), denn sie setzt beim übergebenen Luke-Objekt das dad-Attribut mit der this-Referenz. Damit kennt Luke seinen Vater, getestet in folgender Klasse:

LukeAndDarth.java, Teil 2
public class LukeAndDarth {
  public static void main( String[] args ) {
    Luke luke = new Luke();
    Darth darth = new Darth();
    System.out.println( luke.dad ); // null
    darth.revealTruthTo( luke );
    System.out.println( luke.dad ); // Darth@15db9742
  }
}

Hinweis: In statischen Methoden steht die this-Referenz nicht zur Verführung, da wir uns in Klassenmethoden nicht auf ein konkretes Objekt beziehen.

toString() für equals-Vergleiche?

Einige kreative Programmierer nutzen die toString()-Repräsentation für Objektvergleiche. Etwas der Richtung: Wenn wir zwei Point-Objekte p und q haben, und p.toString().equals(q.toString()) ist, dann sind beide Punkte eben gleich. Doch ist es hochgradig gefährlich sich auf die Rückgabe von toString() zu verlassen aus mehreren Gründen: Offensichtlich ist, dass toString() nicht unbedingt überschrieben sein muss. Zweitens muss toString() nicht unbedingt alle Elemente repräsentieren und die Ausgabe könnte abgekürzt sein. Drittens können natürlich Objekte equals-gleich sein, auch wenn ihre String-Repräsentation nicht gleich ist, was etwa bei URL-Objekten der Fall ist. Der einzige erlaubte Fall für so eine Konstruktion wäre String/StringBuilder/StringBuffer/CharSequence, wo es ausdrücklich um Zeichenketten geht.

Habe ich Gründe vergessen?

Verwandtschaft von Methode und Konstruktor

Methoden und Konstruktoren besitzen beide Programmcode, haben eine Parameterliste, Modifizierer, können auf Objektvariablen zugreifen und this verwenden – das sind ihre Gemeinsamkeiten. Ein schon erwähnter Unterschied ist, dass Methoden einen Rückgabetyp besitzen (auch wenn er nur void ist), Konstruktoren aber nicht. Zwei weitere Unterschiede betreffen die Syntax und Semantik.

Konstruktoren tragen immer den Namen ihrer Klasse, und da Klassennamen per Konvention großgeschrieben werden, sind auch Konstruktoren immer großgeschrieben – Methoden werden in der Regel immer kleingeschrieben. Und Methoden sind in der Regel Verben, die das Objekt anweisen etwas zu tun, Klassennamen sind Nomen und keine Verben.

Der Programmcode eines Konstruktors wird automatisch nach dem Erzeugen eines Objekts von der JVM genau einmal aufgerufen, und zwar als erstes vor allen anderen Methoden. Methoden lassen sich beliebig oft aufrufen und unterliegen der Kontrolle des Benutzers. Konstruktoren lassen sich später nicht noch einmal auf einem schon existierenden Objekt erneut aufrufen und so ein Objekt reinitialisieren. Der Konstruktor-Aufruf ist implizit und automatisch mit new verbunden und kann nicht getrennt vom new gesehen werden.

Zusammenfassend können wir sagen, dass ein Konstruktor eine Art spezielle Methode zur Initialisierung eines Objektes ist.

JVM-Interna: „Ein Java-Compiler setzt Konstruktoren als void-Methoden um, die „<init>“ heißen“.