Eclipse Project 4.5 (Mars) M4

Je länger ich Eclipse benutze, desto seltener beschäftige ich mich mit Release-Dates oder den Features — es sei denn, ich warte auf die Unterstützung von neuen Sprache-Features.

So gingen auch die bisherigen Milestones von 4.5 an mir spurlos vorbei, auch der letzte Milestone M4 vom 12.12. Zusammenfassend Neuerungen, die (für mich) interessanter sind:

https://www.eclipse.org/eclipse/news/4.5/M4/

Assigning stdin to a file
Stdin can now be assigned to a file in the “Common” tab of launch configuration dialogs.

Automatic scroll lock in Console view
Scrolling up in the Console view using keys, mouse wheel, or scroll bar now automatically enables the Scroll Lock mode.

When you scroll down to the end of the console, the scroll lock is automatically released again.

Improved flow analysis for loops
Flow analysis has been improved to more precisely capture the flow of null values in loops. This mainly achieves a reduction of false positive reports from null analysis.

Previously, example method “test1″ would raise a potential null pointer warning at point (3). To correct this issue the merging of information leading towards point (3) has been improved to correctly see that the null value from point (1) can never reach point (3).

In example method “test2″ JDT previously reported a redundant null check at (3), because analysis didn’t see that the assignment directly above could indeed assign a non-null value.

In example method “test3″ it was reported that “o can only be null” at (3), because the information from the two null-assignments wrongly overruled the one assignment from non-null. With improved analysis this is now softened to saying “o may be null”.

The graph on the right hand side illustrates the new composition of flow information: for each relevant point (3) inside a loop, the analysis first merges the flows that lead into (1). This result is concatenated with the partial flow (b.c), which leads from the loop start to point (3). Improved precision has thus been achieved within the design limits of a single AST traversal in order to minimize impact on compiler performance.

https://www.eclipse.org/eclipse/news/4.5/M3:

‘Terminate/Disconnect All’ in Console view
You can invoke the Terminate/Disconnect All action from the Console view’s context menu:

Add inferred lambda parameter types
You can explicitly add the inferred types of the parameters in a lambda expression by invoking the Quick Assist (Ctrl+1) – Add inferred lambda parameter types:

Convert method reference to lambda and back
New Quick Assists (Ctrl+1) have been added to convert…

  • from method reference to lambda expression:Integer::toHexString
  • from lambda expression to method reference:t -> Integer.toHexString(t)

https://www.eclipse.org/eclipse/news/4.5/M2/

Compiler schneller.

https://www.eclipse.org/eclipse/news/4.5/M1/

Word wrap in the Console
A new formatting option has been contributed to the Console view for all I/O consoles: Word Wrap.

The new option is available on the Console view toolbar and in the content popup menu within the Console view.

The new word wrap toolbar and popup menu command

Der http://www.eclipse.org/projects/project-plan.php?planurl=/eclipse/development/plans/eclipse_project_plan_4_5.xml gibt uns noch einen Milestone vor, dann beginnt die Feinarbeit:

  • M5 2015-01-30 4.5M5
  •     2015-02-13 CQ Submission Deadline
  • M6 2015-03-20 .5M6 (API Freeze)
  • M7 2015-05-01 4.5M7 (Feature Freeze)

Interessanter Sicherheits-Bug in 7u51 gefixed

Details unter http://weblog.ikvm.net/2014/01/16/PubliclyReportedOpenJDKVulnerabilityFixedIn7u51.aspx:

import java.lang.invoke.*;
class test extends java.io.FileOutputStream {
  static test t;
  test() throws Exception {
    super(“”);
  }
  protected void finalize() {
    t = this;
  }
  public static void main(String[] args) throws Throwable {
    MethodHandle mh = MethodHandles.lookup().findVirtual(test.class, “open”,
                        MethodType.methodType(void.class, String.class, boolean.class));
    System.out.println(mh);
    try { new test(); } catch (Exception _) { }
    System.gc();
    System.runFinalization();
    mh.invokeExact(t, “oops.txt”, false);
  }
}

Joda-Time auf Java 8 java.time konvertieren

Wie man von Joda-Time zur Java 8 Date&Time-API konvertiert diskutiert der Beitrag http://blog.joda.org/2014/11/converting-from-joda-time-to-javatime.html von Stephen Colebourne.

Der Autor von Joda-Time selbst empfiehlt bei neuen Projekten die Date-Time-API von Java:

If you are writing code in Java SE 8, its time to migrate to java.time, perhaps using ThreeTen-Extra to fill any gaps.

Android Studio basiert auf IntelliJ, Eclipse ist raus

Googles Android-IDE war lange Zeit ein ADT-Plugin für Eclipse. Das ist nun vorbei, das Plugin wird nicht mehr (von Google offiziell) weiterentwickelt. Eine Version auf der Basis der quelloffenen Community Edition von IntelliJ war seit 2 Jahren in Entwicklung, und ist nun die offizielle IDE für Android-Anwendungen. Mit IntelliJ hat man sich sicherlich eine gute Basis ausgesucht, nur wird es viele Eclipse-IDE-Nutzer verprellen, die bei den Shortcuts und der Projektorganisation dazulernen müssen.

Links:

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

Turtle-Grafik

Die Turtle-Grafik (engl. turtle, zu Deutsch Schildkröte) ist eine Idee von Seynour Papert, der damit ein Lehrmodell für den Unterricht schaffen wollte. Populär wurde der Turtle sicherlich durch die „Kindersprache“ LOGO. Aber auch anderswo wurde mit dem Turtle viel gearbeitet. Und so erhielt er viele Namen. Eingeführt in der Oberstufe durch einen Roboter (Robi oder so) bzw. den Hamster Nikki.

Das Turtle-Grundprogramm

Um den (das?) Turtle zu steuern, brauchen wir lediglich ein paar Unterprogramme:

  • void turnright(int winkel)
  • void turnleft(int winkel)
  • void forwd(float step)
  • void back(float step)

Die Implementierung dieser grundlegenden Befehle ist sehr einfach. Wir werden dazu den Winkel und die Position als lokale Variablen einführen und darauf zurückgreifen. Die Unterprogramme werden die Variablen angle, x, y‚ oldx, oldY nutzen:

import java.awt.AWTEvent;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowEvent;

@SuppressWarnings( "serial" )
public class Turtle extends Frame
{
 private double angle = 0, x = 300, y = 300, oldX = 300, oldY = 300;
 private Graphics graphics;

 // Initialisiert Turtle-Grafik und bringt Frame auf den Schirm
 public Turtle()
 {
 setTitle( "Turtle-Grafi" );
 setSize( 600, 600 );
 enableEvents( AWTEvent.WINDOW_EVENT_MASK );
 setVisible( true );
 }

 public void setGraphics( Graphics graphics )
 {
 this.graphics = graphics;
 }

 // Methoden, die den Stift bewegen

 public void turnright( double degree )
 {
 if ( (angle += degree) > 360 )
 angle %= 360;
 }

 public void turnleft( double degree )
 {
 if ( (angle -= degree) < 0 )
 angle %= 360;
 }

 public void forwd( double step )
 {
 back( -step );
 }

 public void back( double step )
 {
 oldX = x;
 oldY = y;

 x -= step * Math.sin( Math.toRadians( angle ) );
 y += step * Math.cos( Math.toRadians( angle ) );

 graphics.drawLine( (int) x, (int) y, (int) oldX, (int) oldY );
 }

 // Events vom Schließen des Fensters abfangen

 @Override
 protected void processWindowEvent( WindowEvent e )
 {
 if ( e.getID() == WindowEvent.WINDOW_CLOSING )
 System.exit( 0 );

 super.processWindowEvent( e );
 }
}

Mit dieser kleinen Basisklasse ist schon eine Menge machbar, wie es uns der folgende Abschnitt uns zeigen wird.

Dreiecke und Kurven

Zum Einstieg in die Turtle-Grafik eignen sich rekursive Grundstrukturen. Dazu bieten sich Dreiecke und Kurven besonders an.

Dreiecke

Das erste darzustellende Objekt wird ein Dreieck sein. Im Dreieck werden weitere Dreiecke erscheinen, was durch Rekursion ein leicht lösbares Problem ist. Die Dreiecke bestehen dabei aus wiederum drei Dreiecken mit der halben Seitenlänge, die in den Spitzen sitzen. Schauen wir uns einmal das Listing an:

import java.awt.Graphics;

final class Dreiecke extends Turtle
{
 public static void main( String args[] )
 {
 new Dreiecke();
 }

 void tri( float len, int deep )
 {
 if ( deep != 0 ) {
 for ( int i = 1; i < 4; i++ ) {
 forwd( len );
 turnright( 120 );         // (a)
 tri( len / 2, deep - 1 ); // (b)
 }
 }
 }

 public void paint( Graphics g )
 {
 setGraphics( g );
 tri( 100, 2 );
 }
}

Werden die die Zeilen (a) und (b) vertauscht, so erscheinen die kleineren Dreiecke in die größeren geklappt.

Mit

tri(len/2, deep-1); back(len); turnright(120);

in der for-Schleife erhalten wir einen weiteren Effekt, nach dem Zeichnen einer Seite wird der Turtle rückwärts gesetzt. Somit ist nicht das innere des Dreieckes gefüllt, sondern die Seiten wandern nach außen.

Peano-Kurve

Bisher wurden von uns nur gleichseitige Dreiecke untersucht. Die Peano-Kurve ist ebenfalls aus einem Dreieck zusammengesetzt, jedoch ist hier die Grundfigur gleichseitig und rechtwinklig. In einem Dreieck passen zwei weitere. Auffallend ist, dass sich Peano-Kurven immer schneiden, andere Kurven machen dies — wie wir sehen werden — nicht immer. Die Peano-Kurve ist das beste Beispiel einer flächendeckenden Kurve.

import java.awt.*;

final class PeanoKurve extends Turtle
{
 final static double SQRT2 = Math.sqrt( 2 );

 public static void main( String args[] )
 {
 new PeanoKurve();
 }

 void peano( double len, int deep )
 {
 if ( deep != 0 ) {
 forwd( len );
 turnleft( 135 );
 peano( len / SQRT2, deep - 1 );

 forwd( len / SQRT2 );
 turnleft( 90 );
 peano( len / SQRT2, deep - 1 );

 forwd( len / SQRT2 );
 turnleft( 135 );
 }
 }

 public void paint( Graphics g )
 {
 setGraphics( g );
 peano( 200, 5 );
 }
}

Koch-Kurve

Das Idee einer Koch-Kurve ist einfach: Ersetzte jede gezeichnete Strecke durch eine Grundfigur. Diese Grundfigur setzt sich aus einer kleineren Grundfigur zusammen, usw. Im Gegensatz zu den anderen Programmen, wird nicht auf jeder Schachtlungstiefe gezeichnet, sondern nur auf der Untersten. Das bedeutet, nur die kleinen Strukturen kommen auf den Schirm. Zur Verdeutlichung das folgende Programm:

import java.awt.*;

final class KochKurve extends Turtle
{
 public static void main( String args[] )
 {
 new KochKurve();
 }

 void koch( double len, int deep )
 {
 if ( deep != 0 ) {
 koch( len / 3, deep - 1 );
 turnleft( 60 );
 koch( len / 3, deep - 1 );
 turnright( 120 );
 koch( len / 3, deep - 1 );
 turnleft( 60 );
 koch( len / 3, deep - 1 );
 }
 else // deep == 0
 forwd( len );
 }

 public void paint( Graphics g )
 {
 setGraphics( g );
 koch( 200, 3 );
 }
}

Die immer gern gesehene Schneeflocke erhalten wir durch zusammenfügen der drei Seiten, die durch die Funktion koch() einzeln gezeichnet wurden. Die paint(…)–Methode erweitern wir durch eine kleine Schleife.

public void paint( Graphics g )
{
 setGraphics(g);

 for (int i=0; i < 3; i++) {
 koch(100, 2);
 turnright(120);
 }
}

Hilbert-Kurven

Mit der Hilbert-Kurve wollen wir das Kapitel der Kurven beenden. Das Grundprinzip wurde deutlich und die wichtigsten Namen genannt — Koch, Peano und Hilbert. In der Hilbert—Kurve wird nun in den Ecken die Funktion wieder rekursiv aufgerufen, gezeichnet wird in jeder Schachtelungstiefe. Hier gilt es sich zu merken: Die Kurve hat weder Berührungspunkte noch Schnittpunkte.

import java.awt.*;

final class HilbertKurve extends Turtle
{
 public static void main( String args[] )
 {
 new HilbertKurve();
 }

 void hilbert( double len, int deep, int direction )
 {
 if ( deep > 0 ) {
 turnleft( direction * 90 );
 hilbert( len, deep - 1, -direction );

 forwd( len );
 turnright( direction * 90 );
 hilbert( len, deep - 1, direction );

 forwd( len );
 hilbert( len, deep - 1, direction );

 turnright( direction * 90 );
 forwd( len );
 hilbert( len, deep - 1, -direction );

 turnleft( direction * 90 );
 }
 }

 public void paint( Graphics g )
 {
 setGraphics( g );
 hilbert( 50, 4, 1 );
 }
}

Ist die Variable direction gerade, so beginnt die Hilbert-Kurve mit einer Links-‚ andernfalls mit einer Rechtsdrehung. Das Programm enthält noch einen Fehler, welchen?

Die ersten Bäume

In diesem Abschnitt wollen wir uns mit Bäumen beschäftigen. Sie sind ein ebenso wie die Kurven ein gutes Beispiel der Turtle-Grafik.

Ein simpler Baum

Beginnen wir mit einem einfachen Baum, wo noch nicht Viel nötig ist. Hier sind einfach ein paar Turtle-Befehle hintereinander gereiht worden.

public void tree( float len )
{
 turnleft( 45 );
 forwd( len );
 back( len );
 turnright( 90 );
 forwd( len );
 back( len );
 turnleft( 45 );
}

Rekursion bringt’s

Nun kann es mit der Baumgenerierung so richtig losgehen. Ein Baum ist ein einfaches Geflecht aus Ästen. Das Gute daran: jeder Ast hat weitere Äste. Das hört sich natürlich schon nach Rekursion an. Wir deklarieren ein Unterprogramm tree()‚ dass eine V-förmige Grundstruktur zeichnet. Beim Zeichnen jedes weiteren Astes wird wieder tree() aufgerufen, bis die Länge eines Astes auf unter 10 schrumpft.

import java.awt.*;

final class Tree extends Turtle
{
 public static void main( String args[] )
 {
 new Tree();
 }

 void tree( double len )
 {
 if ( len > 10 ) {
 turnleft( 45 );
 forwd( len );
 tree( len / 2 );

 back( len );
 turnright( 90 );
 forwd( len );
 tree( len / 2 );

 back( len );
 turnleft( 45 );
 }
 }

 public void paint( Graphics g )
 {
 setGraphics( g );
 tree( 150 );
 }
}

Anstatt mit einer Zweiglänge abzubrechen, kann auch nach Erreichen einer bestimmten Schachtelungstiefe — also die Anzahl rekursiver Aufrufe — abgebrochen werden. Dies wollen wir jetzt einmal versuchen. Zu der Länge eines Astes soll die Schachtelungstiefe und der Zeichenwinkel hinzukommen.

Um etwas Spannung in den Algorithmus zu bekommen, lassen wir den Winkel immer etwas größer werden. Das Ganze sieht dann so aus:

void tree2( float len, int deep, int angle )
{
 if ( deep != 0 ) {
 turnleft( angle );
 forwd( len );
 tree2( len / 2, deep - 1, angle + 3 );

 back( len );
 turnright( 2 * angle );
 forwd( len );
 tree2( len / 2, deep - 1, angle + 3 );

 back( len );
 turnleft( angle );
 }
}

Und wir erhalten mit dem Unterprogramm und der Zeile tree2( 100, 6, 20 ) einen kleinen Baum — doch irgendetwas fehlt! Es ist der Stamm. Um ihn anzufügen bedarf es lediglich kleiner Änderungen.

void tree3( double len, int deep )
{
 if ( deep != 0 ) {
 forwd( len );
 turnleft( 45 );
 tree3( len / 1.5, deep - 1 );

 turnright( 90 );
 tree3( len / 1.5, deep - 1 );

 turnleft( 45 );
 back( len );
 }
}

Doch auch mit Stamm wirkt der Baum zu künstlich. Um dem etwas entgegenzuwirken, wollen wir den Abknickwinkel und ein Verkürzungsverhältnis mit einbauen. Zudem soll der rechte und linke Winkel ein anderer sein. Sie sollen dem Unterprogramm übergeben werden. Hier das Ergebnis:

void tree4( double len, int deep, int angleL, int angleR, double lenL, double lenR )
{
 if ( deep != 0 ) {
 forwd( len );
 turnleft( angleL );
 tree4( len * lenL, deep - 1, angleL, angleR, lenL, lenR );

 turnright( angleL + angleR );
 tree4( len * lenR, deep - 1, angleL, angleR, lenL, lenR );

 turnleft( angleR );
 back( len );
 }
}

Hier können wir viele Parameter variieren und bekommen eine Vielzahl von Bäumen. Mit tree(100, 6, 30, -5, 0.5, 0.75) generieren wir einen Baum im Wind.

Mehr Formenvielfalt

Leider lässt auch dieser Baum seine Herkunft nicht verleugnen. Die Äste sind noch zu gleichmäßig. Um dem ein Ende zu setzen, werden Zufallswerte eingesetzt, damit ein Baum öfters einmal anders aussieht. Um Zufallszahlen mit Hilfe von Funktionen der Java-Bibliothek nutzen zu können, ist das Mathe-Paket einzubinden. Die Funktion rand() wird dann Zufallszahlen zwischen Null und Eins liefern. Sie können als Multiplikatoren zu der Länge oder dem Winkel genommen werden. Die Bilder bekommen dadurch eine ganz andere Wirkung.

Eine ganz andere Möglichkeit ist das Abweichen vom V-förmigen Grundmuster. Es ist aus verschiedenen Gründen sinnvoll, von dieser Form abzuweichen, und eine asymmetrische Figur zu wählen. Die Symmetrie wird insofern gebrochen, dass nicht auf jedes V ein weites folgt, die linke Seite bleibt etwas „unterentwickelt“. Ziel ist ein harmonischeres Bild, und eine natürlichere Form.

void tree5( double len, int deep, int angle, double factor )
{
 if ( deep != 0 ) {
 turnleft( angle );
 forwd( len );
 tree5( len * factor, deep - 1, angle, factor );

 back( len );
 turnright( angle * 2 );
 forwd( len );
 turnright( angle );
 forwd( len );
 tree5( len * factor, deep - 1, angle, factor );

 back( len );
 turnleft( angle * 2 );
 forwd( len );
 turnleft( angle );
 forwd( len );
 tree5( len * factor, deep - 1, angle, factor );

 back( len );
 turnright( angle * 2 );
 forwd( len );
 tree5( len * factor, deep - 1, angle, factor );

 back( len );
 turnleft( angle );
 back( len );
 turnright( angle );
 back( len );
 turnleft( angle );
 }
}

Ein Beispielaufruf: tree5( 50, 4, 30, 0.6 ),

L-Systeme

Bisher war die Umsetzung von Wachstumsprozessen ein aufwändiges Unterfangen. Anstatt Zwei rechts, zwei links zu diktieren, ist es wünschenswert eine Sprache zur Formulierung von Wachstumprozessen einzuführen. Immer ein Programm vor Augen zu haben welches mit Schlüsselwörtern wie forwd(), left()ist auch vom mathematischen Gesichtspunkt her nicht sinnvoll. Im Jahre 1968 führte der Biologe Aristid Lindenmayer die sogenannten L-Svsteme (Lindenmayer-Systeme) zur Beschreibung von Wachstumsprozessen ein. Dieses System entpuppt sich bei näherem Hinschauen als eine kontextfreie Grammatik (CFG). Wie bei der Grammatik so üblich besteht das L-System aus einem Tupel, bestehend aus einem Alphabet V = {a1, …, an}, Produktionsabbildungen P: V → V* wobei V* die Menge aller bildbaren Zeichenketten beschreibt. Mit einer Zeichenkette werden nun die Wachstumsprozesse beschrieben. Dazu werden Turtle-Kürzel eingeführt, die in folgender Tabelle aufgelistet sind.

Zeichen: Reaktion
F: um Schrittweite l nach vorne
f: hebe Schwanz und zeichne nicht
+: Winkel delta gegen den Uhrzeigersinn
-: Winkel delta im Uhrzeigersinn

Tabelle: Befehle des Automaten

Die Konstanten l und d sind Länge und Winkel.Die Zustände können als Tupel verwaltet werden. Die Einträge: x bzw. y ist die Koordinate, alpha der Winkel. Der Start ist mit (0,0,0) festgesetzt. Nach Rechts wird also losgelaufen. Die oben aufgelisteten Operationen angewandt, verändern das Tupel wie in der folgenden Tabelle angegeben.

Befehl: Zustand geht über in
F: (x + l * cos(alpha) , y + l * sin(alpha), alpha)
f: (x + l * cos(alpha), y + l * sin(alpha), alpha)
+: (x, y. alpha + delta)
-: (x, y. alpha – delta)

Tabelle: Änderung des Zustandes

Das L-System wird auch unter dem Namen Graftal geführt. Gelegentlich tauchen auch die Ziffern 0 und 1 auf, um keinen bzw. einen Schritt in die vorgegebene Richtung zu gehen. Eckige Klammern werden ebenso verwendet wie kennengelernt. Beispiel: 11[11]1. Gehe zwei Schritte nach vorne, zeichne dann einen Ast (die Verzweigung) von 2 Einheiten Länge, kehre zum Verzweigungspunkt zurück und ergänze den Stamm um eine Einheit. Einige bekannte Kurven sollen nun in L-System-Notation verdeutlicht werden.

Koch

Wir erinnern uns da sicherlich noch an die Koch-Kurve, bestehend aus 4 Strecken. Der Winkel der Strecken betrug immer 60 Grad, sodass wir in unserem System delta = 60° setzen können. Der Erzeugungs-String ist dann F+F–F+F. Die Abarbeitung folgt von links nach rechts, wie ein normaler mathematischer Ausdruck. Die Interpretation dieses Strings: Der Turtle geht einen Schritt der Länge l vor, dreht sich dann um 60 Grad nach links, geht wieder einen Schritt voraus, dreht sich zweimal um 60 Grad (also dann um 120 Grad) nach links, geht anschließend einen Schritt vor, um dann nach einer erneuten Drehung und Schritt voran zum Ende zu kommen. In der oben geschriebenen Schreibweise hätten wir also eine Produktionsregel, die in der Informatik die Schreibweise F → F+F–F+F bekäme.

Sierpinski-Pfeilspitze

Die gesamte Information über den Aufbau eines Objektes fasst man nun in einem Axiom zusammen. Somit wird die Beschreibung eines Objektes sehr kurz und kann in einer Tabelle leicht beschrieben werden.

Axiom: L
Produktionsregeln: L → +R-L-R+
R → -L+R+L
delta: 60°

Man sieht an diesem Beispiel, wie günstig es ist, mehrere Variablen einzuführen, um das Bild etwas übersichtlicher zu gestalten.

Achtung! Obwohl es nach einer Endlos-Verschachtelung aussieht — L ruft R auf und wieder umgekehrt — läuft das Programm trotzdem zu Ende. Es ist vielmehr dem Programmierer überlassen eine Abbruchbedingung zu implementieren. So beispielsweise das Abbrechen bei einer bestimmten Schachtlungstiefe oder Stammlänge.

Drachen-Kurve

Axiom: D
Produktionsregeln: D → -D++E
E → D–E+
delta: 60°

Bäume und Büsche

Nachdem wir das Grundsystem kennengelernt haben, dürfte es nicht schwerfallen, fraktale Gewächse zu entwickeln. Die Frage ist hier nur: Wie kann man eine Struktur, die sich verzweigt in einer Zeichenkette darstellen, die das L—System letztendlich verwendet? Notwendig dazu ist die Einführung zweier Symbole: [ und ]. Gelangt der Turtle bei der Interpretation der Zeichenkette an eine eckige Klammer, so muss er die Position und die Richtung des Turtles sichern und später wieder restaurieren. Nun hier ein Beispiel für eine krautartige Pflanze:

Axiom: F
Produktionsregeln: F —> F[+F]F[—F]F
delta: 25,7°

und noch ein Kraut:

Axiom: B
Produktionsregeln: F → FB
B → F[+B]F[—B]+B
delta: 25,7°

Bisher waren die vorgestellten Systeme immer deterministisch, das heißt es gab ein absehbares Ende und eine voraussehbare Form. Wenn der Zufall in ein L-System einzieht, so nennt man dies nicht-deterministisch Systeme stochastisch. Doch wenn der Zufall einfließt ist eine Aussage über das Wachstum schwierig. Dennoch ist es wichtig zu bestimmen wie groß die Wahrscheinlichkeit sein soll, dass ein Ereignis eintritt. Wenn der Baum z.B. nach rechts driften soll, so kann man Umgangssprachlich sagen: In 2 von drei Fällen gehe nach rechts. Um dies auszudrücken erweitern wir die Schreibweise ein wenig, und fügen die Wahrscheinlichkeit mit an. Hier das Beispiel von Kraut Nr. 3. (Wahrscheinlichkeit wurde
mit R abgekürzt.)

Axiom: F
Produktionsregeln: F → F[+F]F[—F]FR 1/3
F → F[+F]FR 1/3
F → F[—F]FR 1/3
delta: 25,7°

Die Anzahl der Produktionsregeln bestimmt also immer den Nenner des Bruches.

Etwas entfernt von der Pflanzen soll abschließend das L-System einer zufälligen Koch-Kurve aufgezeigt werden:

Axiom: F
Produktionsregeln: F → F-F++F—FR 0.5
F → F+F–F+FR 0.5
delta: 60°

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.