Dokumentiert http://edmundkirwan.com/general/junit.html:

Dokumentiert http://edmundkirwan.com/general/junit.html:

Ein ziemlich intelligenter Trick, um Daten vom Server zum Client zu senden sind Animated GIFs. Ein GIF kann beliebig viele Frames haben und der Client hält die Verbindung offen um noch “den Rest” zu lesen.
https://github.com/videlalvaro/gifsockets ist eine JVM-Bibliothek in Java und Clojure, das genau das macht: Einen Server zu bauen, der Frame für Frame zum Client streamt. Es gibt ein Start-Frame, dann kann das Serverprogramm beliebig viele Frames senden und zum Schluss ein Abschluss-Frame – dafür gibt es eine API. Allerdings kodiert das Beispiel die Daten (hier Text) als Grafik “Graphics drawString()”; interessanter wäre es, Binärdaten über Farbwerte zu kodieren und auf dem Client dann auszulesen – hier ist also noch Platz für ein weiteres Open-Source-Projekt.
Natürlich brauch so etwas nicht wirklich, wenn man WebSockets nutzen kann. Doch es ist ein interessanter Hack.
http://download.eclipse.org/eclipse/downloads/drops4/S-4.4M7-201405010200/news/
Für mich ist wichtig:
Java 8: Java™ 8 is here, and JDT fully supports it:
Before:
After the Quick Assist (Ctrl+1), the 6 lines are condensed into 1:

Heute kommt auch der erste Release Candidate (RC) raus.
Von einer Datenbank können verschiedene Informationen ausgelesen werden. Zum einen sind dies Informationen zu einer bestimmten Tabelle, zum anderen Informationen über die Datenbank selbst.
Bei der Abfrage über alle Spalten müssen wir die Struktur der Datenbank kennen, insbesondere dann, wenn wir allgemeine Abfragen vornehmen und die passenden Daten herauslesen wollen. So liefert SELECT * FROM Item ein ResultSet mit der Anzahl der Spalten, wie sie die Tabelle Item hat. Doch bevor wir nicht die Anzahl und die Art der Spalten kennen, können wir nicht auf die Daten zugreifen.
Um diese Art von Informationen, so genannte Metadaten, in Erfahrung zu bringen, befindet sich die Klasse ResultSetMetaData, mit der wir diese Informationen erhalten, unter den SQL-Klassen. Metadaten können für jede Abfrage angefordert werden. So lässt sich unter anderem leicht herausfinden:
Um Anzahl und Art der Spalten einer Bestelltabelle herauszufinden, werden wir zunächst ein ResultSet mit stmt.executeQuery(„SELECT * FROM Item“) erzeugen und dann via getMetaData() ein ResultSetMetaData-Objekt erfragen. Das ResultSetMetaData-Objekt besitzt viele Methoden, um Aussagen über die Tabelle und die Spalten zu treffen. So fragen wir mit getColumnCount() nach, wie viele Spalten die Tabelle hat. Anschließend lässt sich für jede Spalte der Name und Typ erfragen:
String url = "jdbc:hsqldb:file:TutegoDB;shutdown=true";
String sql = "SELECT * FROM ITEM";
try ( Connection con = DriverManager.getConnection( url, "sa", "" );
Statement stmt = con.createStatement();
ResultSet rs = con.createStatement().executeQuery( sql ) ) {
ResultSetMetaData meta = rs.getMetaData();
int numerics = 0;
for ( int i = 1; i <= meta.getColumnCount(); i++ ) {
System.out.printf( "%-20s %-20s%n", meta.getColumnLabel( i ),
meta.getColumnTypeName( i ) );
if ( meta.isSigned( i ) )
numerics++;
}
System.out.println();
System.out.println( "Spalten: " + meta.getColumnCount() +
", Numerisch: " + numerics );
}
interface java.sql.ResultSet
extends Wrapper, AutoCloseable
interface java.sql.ResultSetMetaData
extends Wrapper
Allen folgenden Methoden wird ein int übergeben, das die Spalte kennzeichnet:
Alle Methoden können eine SQLException auslösen.
Metadaten sind auch für die gesamte Datenbank abfragbar. Beispiele für diese Informationen sind:
Sind Informationen über die Datenbank gefragt, so lassen sich über Metadaten eines DatabaseMetaData-Objekts beispielsweise Datenbankeigenschaften des Herstellers herausfinden. Zunächst benötigen wir dazu ein DatabaseMetaData-Objekt, das uns getMetaData() von einer Connection gibt. Das DatabaseMetaData-Objekt deklariert eine große Anzahl Methoden:
DatabaseMetaData meta = con.getMetaData(); System.out.println( "Product name " + meta.getDatabaseProductName() ); System.out.println( "Version: " + meta.getDatabaseProductVersion() ); System.out.println( "Maximum number of connections: " + meta.getMaxConnections() ); System.out.println( "JDBC driver version: " + meta.getDriverVersion() ); System.out.println( "Supports update in batch: " + meta.supportsBatchUpdates() ); System.out.println( "Supports stored procedures: " + meta.supportsStoredProcedures() );
Groovy (http://groovy.codehaus.org/) ist eine objektorientierte Skriptsprache, die auf einer JVM läuft und vollen Zugriff auf alle Java-Bibliotheken bietet. Die Sprache hat viele interessante Eigenschaften, die sie zu Java X machen. Groovy setzt auf der Standard-Java-Syntax auf und erweitert diese.[1] Einige Höhepunkte:
| Groovy-Feature | Beispiel |
| Statt System.out.print(…)/println(…) reicht ein print bzw. println, und dann muss das Argument auch nicht in runden Klammern stehen. | println 1 + 2 print „Wow“ |
| Anweisungen müssen nicht immer mit einem Semikolon abgeschlossen werden, sondern nur dann, wenn mehrere Anweisungen in einer Zeile stehen. | print „Wow“ print „Wow“; print „Wow“ |
| Variablen müssen nicht mit einem Typ deklariert werden, das gilt auch bei catch oder Methoden/Konstruktoren. | def age = 40 def greet( name ) { print „Hallo “ + name } try { } catch ( e ) { } |
| Zeichenketten lassen sich mit einfachen oder doppelten Anführungszeichen angeben. Einzelne Zeichen (char/Character) müssen besonders aufgebaut werden. | print „Ja“ == ‚Ja‘ // true def sign = „-“ as char |
| Strings in doppelten Anführungszeichen sind besondere GStrings: Enthalten sie $variable bzw. ${ausdruck}, so wird der Inhalt der Variablen bzw. der ausgewertete Ausdruck eingesetzt. | def one = 1 print „$one plus $one macht ${1+1}“ // 1 plus 1 macht 2 |
| Strings können über mehrere Zeilen laufen, wenn sie in „““ oder “‘ eingeschlossen sind – folgt ein Backslash am Ende der Zeile, wird kein Zeilenumbruchzeichen eingefügt. | print „““ Zeile 1 Zeile 2\ Weiter mit Zeile 2 „““ |
| Alles ungleich 0 und null ist true. | if ( 1 ) print ‚Zweig wird genommen‘ |
| Groovy definiert einen neuen Datentyp für Bereiche (engl. ranges). | def numbers1 = 0..9 def numbers2 = 0..<10 |
| Erweiterte Zählschleife unter Berücksichtigung von Bereichen, bzw. rechts von in steht ein Iterable wie beim erweiterten for. | for ( i in 0..<10 ) print i // 0123456789 |
| == bei Referenzen bedeutet equals(…)-gleich; ein Identitätsvergleich realisiert is(…). | def heinz = ‚Heinz‘ print heinz == ‚Heinz‘ // true |
| Operatoren können überladen werden, und die Anwendung von Operatoren entspricht Methodenaufrufen, etwa + von plus(…), ++ von next(…) oder [] von getAt(…). | println 1 + 2 * 3 // 7 println 1.plus(2).multiply(3) // 9 println 1.plus(2.multiply(3)) // 7 |
| Alle Comparable-Objekte (und damit etwa String, BigInteger, BigDecimal) können mit ==, !=, <, >, <= und >= verglichen werden. Die Ordnung liefert compareTo(…). | def heinz = ‚Heinz‘ print heinz < ‚Werner‘ // true |
| Ist in Java nur java.lang standardmäßig importiert, ist es bei Groovy viel mehr, etwa noch java.io, java.util, java.net und noch einige. | print new File(‚file.txt‘).exists() |
| Statt explizit auf Datenstrukturklassen für Listen und Mengen zurückzugreifen, bietet Groovy eine spezielle Syntax. | def primes = [ 2, 3, 5, 7] print primes[ 0 ] def dic = [ ‚rot‘ : ‚red‘, ‚blau‘ : ‚blue‘ ] print dic[‚rot‘] // red |
| Die Operatoren ?. und ?: (Elvis-Operator) verhindern null-Zugriffe. | def name = ‚Chris‘ println name ?: ‚Kein Name‘ // Chris name = null println name ?: ‚Kein Name‘ // Kein Name |
| Der Zugriff auf Zeichen über [] ist bei den Zeichenkettenklassen String, StringBuffer, StringBuilder möglich. | def s = ‚Ooog‘ print s[0] // O |
| Der Zugriff über [] lässt auch Bereiche zu. | def s = „tutego“ print s[ 0, 1, 3..5 ] // tugeo def t = new StringBuilder( „tutego“ ) t[ 1..4 ] = „X“ print t // tXo |
| Der Operator << hängt Dinge an Strings (Rückgabe ist dann StringBuffer), Listen oder Dateien an. | def s = ‚oger‘ def sb = ‚Das ist ‚ << s << ‚ oder?‘ print sb // Das ist oger oder? def file = new File(„out.txt“) file << „Zeile 1“ |
| Reguläre Ausdrücke werden mit einer eigenen Syntax direkt von der Sprache unterstützt; =~ ist ein find, ==~ ein match. | print ‚2010‘ ==~ /\d+/ |
| erweitertes switch-case etwa mit regulären Ausdrücken und Bereichen | switch ( 42 ) { case 0..100 : println ‚ist zwischen 0..100‘; break case Integer : println ‚ist Integer‘; break case { it % 2 == 0 }: println ‚ist gerade‘; break case ~/\d\d/: println ’42 passt auf das Pattern‘; break } |
| Datentyp für Dauer und spezielle Eigenschaften für Datumswerte und überladene Operatoren zum leichten Rechnen mit dem Paket groovy.time | use ( groovy.time.TimeCategory ) { def today = new Date() def tomorrow = today + 1.day print „Morgen: $tomorrow, nächstes Jahr ${today + 1.year}“ } |
| Closures als Codeblöcke werden unterstützt und finden überall in der Groovy-API Anwendung. | new File( „file.txt“ ).eachLine { println it } def names = [ „Charisma“, “ „, „Tina“, „“ ] print names.findAll { ! it.trim().isEmpty() } // [Charisma, Tina] |
| Setter/Getter müssen nicht aufgerufen werden; beim Zugriff ref.property wird automatisch der Setter/Getter aufgerufen. | def p = new Point( 10, 20 ) print p.location.x // 10.0 |
| In Methoden mit Rückgabe kann das Schlüsselwort return entfallen. | def add( a, b ) { a + b } |
| Default-Parameter bei Methodendeklarationen | static tax( cost, taxRate = 19 ) { cost * taxRate / 100 } println tax( 100 ) // 19 println tax( 100, 7 ) // 7 |
| Methoden und Klassen sind standardmäßig public, nicht paketsichtbar wie bei Java. Groovy erstellt automatisch Setter/Getter. | class Person { def name } |
| Mit der Klassenannotation @Immutable wird ein Typ unveränderbar, mit @Singleton ein Singleton mit einem privaten Konstruktor und öffentlichem Attribut instance für die eine Instanz. | @Immutable class Pair { String val1, val2 } @Singleton class AppWindow { } |
| Diverse Builder-Klassen erleichtern den Aufbau von hierarchischen XML- oder Swing-Bäumen ebenso wie Ant-Build-Skripten. | import groovy.xml.MarkupBuilder def writer = new StringWriter() new MarkupBuilder( writer ).html { head { title ‚Zählen mit Graf Zahl‘ } body { h1 ( ‚Willkommen‘ ) p { ul { (1..10).each { li it } } a( href:“’http://stupidedia.org/stupi/Graf_Zahl“‘, ‚Graf Zahl‘ ) } } } println writer |
Eigenschaften von Groovy mit Beispiel
Um Groovy-Skripte und Programme auszuführen, bieten sich drei Wege an:
Das Eclipse-Plugin unter http://groovy.codehaus.org/Eclipse+Plugin leistet gute Arbeit und wird ständig weiterentwickelt. Auf der Webseite ist der Update-Link genannt, sodass Groovy-Eclipse über den Update-Manager installiert werden kann.
Ist Eclipse neu gestartet und das Plugin installiert, kann jedes Java-Projekt um Groovy-Unterstützung erweitert werden. Bei einem Java-Projekt aktiviert die Aktion Configure • Convert to Groovy Project im Kontextmenü genau diese Groovy-Unterstützung, sodass im Projektbaum die Groovy-Bibliotheken auftauchen.
File • New • Other… ermöglicht zum einen im Zweig Groovy das Erstellen eines neuen Groovy-Projekts (durch die Konvertierung eines existierenden Java-Projekts ist das nicht mehr nötig) und zum anderen mit Groovy Class das Erstellen einer Groovy-Klasse. Bei dieser Option lässt sich ein Paket- und Klassenname eingeben (etwa com.tutego.insel.script und GroovyBabe), und dann öffnet Eclipse den Groovy-Editor.
Löschen wir die Klassendeklaration und setzen nur die zwei Zeilen in die Datei:
package com.tutego.insel.script
print „Hallo Groovy“
Ausgeführt wird das Groovy-Skript im Kontextmenü (oder Run-Menü) mit Run As • Groovy Skript.
Um Groovy als Skriptsprache aus einem Java-Programm heraus zu nutzen, können wir wieder auf die Skript-API zurückgreifen. Wenn es sich bei Eclipse schon um ein Groovy-Projekt handelt, ist ein JAR schon im Klassenpfad eingebunden, und es ist nichts zu tun. Andernfalls bekommen wir von der Webseite http://groovy.codehaus.org/Download unter Download zip: Binary Release ein fast 30 MiB großes ZIP-Archiv wie groovy-binary-2.2.2.zip, wo groovy-all-2.2.2.jar im Ordner embeddable liegt und das wir in den Klassenpfad mit aufnehmen.
Ein kleines Beispiel:
ScriptEngine engine = new ScriptEngineManager().getEngineByName( "groovy" );
System.out.println( engine.eval( "(1g..42g.gcd(56g)).sum()" ) ); // 105
[1] Bis auf sehr kleine Ausnahmen ist jedes Java-Programm ein Groovy-Programm.
Eine der Schwachstellen in der Datumsverarbeitung ist das Fehlen eines Typs für Dauern (wenn wir von TimeUnit einmal absehen). Ein eigenständiger Typ bringt Vorteile, wenn es zum Beispiel darum geht, Dauern zu addieren (»Was ergibt 1 Woche plus 2 Monate?«) oder zu vergleichen (»Ist 1 Stunde mehr als 123456789 Millisekunden?«). Zwar lassen sich mit der add(…)-Methode von Calendar einzelne Segmente ändern, und dadurch lässt sich ein früherer oder späterer Zeitpunkt ansteuern, aber das ist wenig objektorientiert. Besser ist ein eigener Datentyp, der auch Operationen anbietet, um die Dauer auf ein Calendar- oder Date-Objekt zu setzen.
Im Rahmen der W3C-XML-Schema-Unterstützung gibt es Klassen, unter anderem den Typ Duration für Dauern nach der gregorianischen Zeit. Die Klasse liegt jedoch nicht im java.util-Paket, sondern wegen ihres XML-Bezugs im Paket javax.xml.datatype (wo es neben XMLGregorianCalendar nahezu alleine liegt). Exemplare von Duration werden auch von keinem Konstruktor angelegt, sondern von einer Fabrikklasse DatatypeFactory. Beispiel: Lege ein Duration-Objekt mit der Dauer von 1 Tag und 2 Stunden an:
Duration d = DatatypeFactory.newInstance().newDuration(true, 0, 0, 1, 2, 0, 0 ); System.out.println( d ); // P0Y0M1DT1H0M0S
Die DatatypeFactory bietet diverse Fabrikmethoden zum Anlegen der Duration-Objekte. Die Parameterlisten sind wie im Beispiel mitunter recht lang – in der längsten Variante gibt es einen Indikator für ein Vorzeichen, Jahr, Monat, Tag, Stunden, Minuten, Sekunden (keine Millisekunden oder genauer), also mit sieben Parametern. Ein Builder-Pattern zum Aufbau der Objekte wäre nett gewesen … abstract class javax.xml.datatype.DatatypeFactory
Die Duration-Ausgabe im Beispiel über toString() liefert eine besondere String-Repräsentation, die für XML-Dokumente interessant ist, aber andere Methoden sind interessanter. Eine grobe Einteilung ergibt:
Beispiel: Addiere die Dauer von 2 Monaten und 3 Tagen, und berechne, wo wir dann relativ zu heute stehen:
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); Duration d1 = datatypeFactory.newDurationYearMonth( true, 0, 2 ); Duration d2 = datatypeFactory.newDuration( true, 0, 0, 3, 0, 0, 0 ); Duration sum = d1.add( d2 ); Date date = new Date(); System.out.printf( "%tF%n", date ); // 2011-06-21 sum.addTo( date ); System.out.printf( "%tF%n", date ); // 2011-08-24
Intern speichert die Duration-Implementierung jedes einzelne Segment und legt es nicht zu einer Zahl, etwa Sekunden zusammen. Das wäre auch nicht möglich, da die Anzahl Tage im Monat und im Jahr nicht immer gleich sind (dass zeigen uns der Februar und Schaltjahre). Wenn wir auf dem 1.1. einen Monat addieren, wollen wir beim 1.2. auskommen, und wenn wir bei 1.2. beginnen und einen Monat addieren, soll der 1.3. das Ergebnis sein. Beispiel: Additionen eines Monats auf einen Kalender:
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); Duration month = datatypeFactory.newDurationYearMonth( true, 0, 1 ); Calendar cal = new GregorianCalendar( 2012, Calendar.JANUARY, 1 ); month.addTo( cal ); System.out.printf( "%tF%n", cal); // 2012-02-01 month.addTo( cal ); System.out.printf( "%tF%n", cal); // 2012-03-01
Da die Anzahl der Tage im Monat und im Jahr beweglich ist, sind bei add(…) und substract(…) nur gewisse Kombinationen möglich. Es gibt Operationen, die Duration nicht ausführen kann und mit einer IllegalStateException bestraft. Während innerhalb der Gruppe Sekunden, Minuten, Stunden und Tage beliebig addiert und subtrahiert werden können, ist der Übergang nach Monat und Jahr problematisch, insbesondere bei Subtraktionen. Beispiel: 1 Monat minus 1 Tag ist genauso wenig möglich wie 1 Jahr minus 1 Tag:
DatatypeFactory factory = DatatypeFactory.newInstance(); Duration year = factory.newDuration( true, 1, 0, 0, 0, 0, 0 ); Duration month = factory.newDuration( true, 0, 1, 0, 0, 0, 0 ); Duration day = factory.newDuration( true, 0, 0, 1, 0, 0, 0 ); year.subtract( day ); // N IllegalStateException month.subtract( day ); // N IllegalStateException
Beim Vergleichen zweier Dauern gibt es vier unterschiedliche Ergebnisse, und daher implementiert Duration auch nicht die bekannte Comparable-Schnittstelle. Der Grund ist, dass einige Vergleiche nicht endscheidbar sind. So sind 30 Tage sind nicht automatisch 1 Monat, 365 Tage nicht automatisch 1 Jahr. Die compare(…)-Methode liefert Ganzahlen, die den jeweiligen Ausgang dokumentieren:
| Vergleichsergebnis | Beispiel | Konstante |
| Dauer1 ist kürzer als Dauer2. | 1 Minute ist kürzer als 100 Sekunden | DatatypeConstants.LESSER |
| Dauer1 ist länger als Dauer2. | 1 Tag ist länger als 1 Minute | DatatypeConstants.GREATER |
| Dauer1 ist gleichlang Dauer2. | 1 Minute ist gleich 60 Sekunden | DatatypeConstants.EQUAL |
| Dauer1 ist unvergleichbar mit Dauer2. | 30 Tage sind nicht automatisch 1 Monat | DatatypeConstants.INDETERMINATE |
Ausgang von Vergleichen zwischen Duration-Objekten Beispiel: Vergleiche 30 Tage mit 1 Monat:
DatatypeFactory factory = DatatypeFactory.newInstance(); Duration month = factory.newDurationYearMonth( true, 0, 1 ); Duration thirtyDays = factory.newDuration( true, 0, 0, 30, 0, 0, 0 ); System.out.println( month.compare( thirtyDays ) == DatatypeConstants.INDETERMINATE ); // true System.out.println( month.isLongerThan( thirtyDays ) ); // false System.out.println( thirtyDays.isLongerThan( month ) ); // false
Wir sprechen bei Duration daher auch nur von einer partiellen Ordnung statt von einer vollständigen Ordnung.
abstract class javax.xml.datatype.DatatypeFactory
Seit dem in Java 8 die Java Date & Time API eingezogen ist, muss man nicht mehr zu diesen Typen greifen, es sei denn, mann arbeitet direkt mit der XML-API.
http://www.heise.de/newsticker/meldung/TIBCO-kauft-Jaspersoft-2179430.html
Eclipse BIRT halte ich persönlich für die professionelle Losung.
Erstes offenes Seminar in Dortmund, weitere Seminarorte und Termine folgen.
Inhalte und Details: http://www.tutego.de/seminare/java-schulung/java-einfuehrung-seminar-java-1-grundlagen-schulung-java-einsteiger-kurs.html
Trainer voraussichtlich: Christian Ullenboom
Die quelloffene Bibliothek ScreenFX bringt Stages auf unterschiedliche Monitore und kümmert sich um die korrekten Größenänderungen usw. 
Tastaturcodes lassen sich für die Umschaltung definieren. Standardmäßig ist die Bibliothek mit Java 8 kompiliert.
Weitere FX-Komponenten unter http://www.tutego.de/java/javafx-komponenten.htm.
http://download.java.net/jdk8u20/changes/jdk8u20-b11.html
Interessant finde ich Persistent store for compiled scripts.
Details unter http://lucene.apache.org/. Mit Java 8 gibt es keine Probleme.