Inselraus: Details zur OpenJDK-Geschichte

Obwohl OpenJDK unter der GPL stand, enthielt es doch Teile wie den Font-Renderer, Sound-Unterstützung, Farbmanagement oder SNMP-Code, die als binäre Pakete beigelegt wurden, weil etwa die Rechte zur Veröffentlichung fehlten. Sun nennt diese Teile, die etwa 4 % vom JDK 6 ausmachen, belasteten Code (engl. encumbered code)[1]. Das hinderte puristische Linux-Distributoren daran, OpenJDK auszuliefern. RedHat startete im Juni 2007 das Projekt IcedTea, um diese binären Teile auf der Basis des OpenJDK durch GPL-Software zu ersetzen. So basiert der Font-Renderer zum Beispiel auf FreeType[2] und das Farbmanagement auf little CMS[3]. Mit diesen Ersetzungen erfüllte das OpenJDK mit IcedTea im Juni 2008 die Anforderungen des Technology Compatibility Kit (TCK) von Sun und ist in der Öffentlichkeit seither unter dem Namen OpenJDK 6 bekannt. Daraufhin floss das OpenJDK 6 plus der Ersetzungen unter der GPLv2 in Linux-Distributionen wie Fedora und Debian ein.

Das OpenJDK bildet die Basis von Java 8, und jeder Entwickler kann sein eigenes Java zusammenstellen und beliebige Erweiterungen veröffentlichen. Damit ist der Schritt vollzogen, dass auch Java auf Linux-Distributionen Platz finden darf, die Java vorher aus Lizenzgründen nicht integrieren wollten.

Auch wenn es sich so anhört, als ob das Oracle JDK bzw. OpenJDK das Gleiche sei, ist das nicht ganz richtig: Zwar basieren Oracle JDK und OpenJDK auf den gleichen Quellen (bei der Version 7 etwa zu 95 %), doch sind beim Oracle JDK immer noch proprietäre Dinge enthalten, und nicht alles ist hundertprozentig quelloffen und GPL. Das gilt für die Version 7 wie für die Version 6. Das Oracle JDK steht unter der Binary Code License; genau die muss jeder abnicken, der das JDK von der Webseite laden möchte.

Bei der 6er-Reihe kommt noch eine Besonderheit dazu, wie es die Versionsnummern[4] ganz gut zeigen. Während das Oracle JDK zum Beispiel im Juni 2011 bei Versionsnummer 1.6.0_26-b03 steht, ist das OpenJDK bei Version 6 b22. Die Versionsnummern sind deshalb völlig unabhängig, weil beide Projekte auch unabhängig voneinander laufen. Das hat mit der Geschichte zu tun. Nach der Entwicklung des JDK 6, das nicht unter der GPL steht, ging es mit dem JDK 7 logisch weiter. Aus dem JDK 7 (Build 10) entstand dann OpenJDK, das heute mit der Versionsnummer OpenJDK 7 genannt wird. OpenJDK 7 und JDK 7 entwickeln sich Hand in Hand, und Code-Änderungen gehen mal in die eine Richtung und mal in die andere.

Jetzt kommt die Besonderheit: Das OpenJDK 6 entstand nicht, wie vermutet werden könnte, aus dem Oracle JDK 1.6, sondern aus dem OpenJDK 7 (Build 20). Es wurden nur Java 7-Eigenschaften entfernt. So läuft das auch bis heute: Die meisten Änderungen am OpenJDK 6 sind Backports von OpenJDK 7. Änderungen am OpenJDK 7 stammen überwiegend von Oracle, und häufig ist es die Firma RedHat, die diese Änderungen in OpenJDK 6 portiert. Zwischen dem OpenJDK 6 und dem JDK 1.6 gibt es einen Quellcodeaustausch bei Bug-Fixes, doch die Codebasis ist unterschiedlich. Oracle JDK 6 ist im Wartungsmodus, und großartige Veränderungen passieren bis auf Fehlerbereinigungen nicht.

Oracle JDK 8 ist die Version, die die Download-Seite von Oracle anbietet; das OpenJDK 8 liegt auf einem eigenen Server http://openjdk.java.net/projects/jdk8/. Das OpenJDK bildet die Referenzimplementierung für Java SE, nicht das Oracle JDK.

[1]  http://www.sun.com/software/opensource/java/faq.jsp#h

[2]  http://www.freetype.org/

[3]  http://www.littlecms.com/

[4]  http://gist.github.com/925323

Eric Lippert schreibt über „Top 10 Worst C# Features“

http://www.informit.com/articles/article.aspx?p=2425867

Auch interessant für Java, und erstmalig für mich ein offizieller Hinweis, das C# Dinge von Java geerbt hat, was MS immer verneint. Eric ist:

During his sixteen years at Microsoft he was a developer of the Visual Basic, VBScript, JScript and C# compilers and a member of the C# language design committee; he is now a C# MVP.

 

Java SE 8u45 verfügbar

Wie man schon gewohnt ist mit Sicherheitsupdates. Details und Download unter http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html, http://www.oracle.com/technetwork/java/javase/documentation/8u-relnotes-2225394.html, http://www.oracle.com/technetwork/java/javase/8u45-relnotes-2494160.html, http://www.oracle.com/technetwork/java/javase/2col/8u45-bugfixes-2494164.html.

So viel ist vom Bug-Fixing aber nicht passiert.

Java in den Sony-EMails

Ich habe einmal in den https://wikileaks.org/sony/emails/ nach Java gesucht und (auf den ersten Blick) nichts interessantes gefunden.

EMails Search

Viele Werbe-EMails stammen von Azul (“Zing® now available for Java 8”, “Azul Zulu now available for Java 8”), einige Reiseplanungen, doch das hat mich zum Lachen gebracht:

Couple hundred dollars for Cambodia and Java (not sure what the dollar is called in Java. Maybe it’s the same?)

Und echt banales wie

you’ve been on my mind…
When things quite down (ha!) I’ll come by for a cup of morning java.
Sending you much love.
XXXXXXXXXXXXXXXX

Documents Search

Das ergibt nach Java satte 30.287 Ergebnisse. Darunter Dokumente wie https://wikileaks.org/sony/docs/05/docs/eBooks/Hacking_The_Next_Generation.pdf (Hier sind viele PDFs von O’Reilly verlinkt, wer also “günstig” an Ebooks kommen will …)

Viele Dokumente sind Specs aus diversen Quellen zusammengesammelt.

Findet ihr was Spannendes?

Neue Termine für öffentliche Java-Seminare in Dortmund

Java Grundlagen: 04.05.-08.05.15 (KW 19), 29.06.-03.07.15 (KW 27), 07.09.-11.09.15 (KW 37), 02.11.-06.11.15 (KW 45)

Java für Fortgeschrittene: 18.05.-22.05.15 (KW 21), 20.07.-24.07.15 (KW 30), 28.09.-02.10.15 (KW 40), 23.11.-27.11.15 (KW 48)

Java für C#-/C++-Umsteiger: 13.04.-17.04.15 (KW 16), 08.06.-12.06.15 (KW 24), 17.08.-21.08.15 (KW 34), 19.10.-23.10.15 (KW 43)

Offtopic: Praktikumsstellen verfügbar

Die Digitale Erlebnis-Center GmbH beschäftigt sich seit April 2011 intensiv mit dem Aufbau eines PC-/und Spiel-Konsolen-Museums.

Aufgaben

– Gestaltung und Entwurf interaktiver Oberflächen unter Berücksichtigung existierender Frameworks
– Auswahl und Integration von Emulatoren für Computer und Spiel-Konsolen in der musealen Gestaltung
– Recherchetätigkeiten und Erstellung von Texten über Hardware und Software

Qualifikation

– Kreativität und eine hohe Internetaffinität, praktische Erfahrung in HTML, CSS3, JavaScript. Java ist von Vorteil
– Praktische Erfahrung in Linux, Windows und grundlegender Systemkonfiguration
– Systematische, strukturierte und selbstständige Arbeitsweise mit hohem Qualitätsbewusstsein
– Team- und Kommunikationsfähigkeit, gut und sicher im Ausdruck
– Hintergrundwissen über Computer der 1980er Jahre und der Computerspielszene sind von Vorteil

Wir bieten

– Freundliche Arbeitsatmosphäre und Unterstützung bei beruflicher und persönlicher Weiterentwicklung
– Eigenverantwortliche Gestaltung des Aufgabenbereichs unter Einbringung eigener Präferenzen
– Freie Arbeitszeitgestaltung durch Heimarbeit
– Das Praktikum wird gering vergütet

http://www.meinpraktikum.de/praktikum/digitales-erlebnis-center-gmbh/jobs/praktikum-im-computer-konsolen-museum

Heute feiern wir …

… den Pi-Day (https://de.wikipedia.org/wiki/Pi-Tag).

Er findet jedes Jahr am 14. März statt und geht zurück auf die US-amerikanische Datumsschreibweise 3/14 oder die ISO-Schreibweise -3-14, denn der numerische Wert von π auf zwei Dezimalen gerundet ist 3,14. Besonders genaue Anhänger dieses Tages feiern um 1 Uhr 59 und 26 Sekunden und erreichen die Kreiszahl damit bis zur siebten Nachkommastelle, 3,1415926. Im Jahr 2015 wird Pi um 9 Uhr 26 und 53 Sekunden sogar das erste mal, durch die Passende 15 der Jahreszeit bis zur neunten Nachkommastelle erreicht.

Average number of lines per method in the JDK

The JDK itself can help us to count the lines of code, we just need to parse the source and get the method bodies in a String representation–then we can count the lines. A quick statistic from the new Java 8 Stream API will give us the numbers.

Code first:

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TreeScanner;

public class AverageNumberOfLinesInJDKFinder {
  public static void main( String[] args ) throws IOException {

    String[] files = findAllJavaSourceFiles( "C:/Program Files/Java/jdk1.8.0/src/" );
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

    try ( StandardJavaFileManager fileManager = compiler.getStandardFileManager( null, null, null ) ) {
      CompilationTask task = compiler.getTask( null, fileManager, null, null, null,
                                               fileManager.getJavaFileObjects( files ) );

      JavacTask javacTask = (JavacTask) task;
      Iterable<? extends CompilationUnitTree> trees = javacTask.parse();

      LineCountingVisitor lineCountingVisitor = new LineCountingVisitor();
      for ( CompilationUnitTree compilationUnitTree : trees )
        compilationUnitTree.accept( lineCountingVisitor, null );

      DoubleSummaryStatistics stats = lineCountingVisitor.numberOfLines.stream().mapToDouble( d -> d ).summaryStatistics();
      System.out.println( stats );
    }
  }

  static String[] findAllJavaSourceFiles( String base ) throws IOException {
    final List<String> result = new ArrayList<String>();

    Files.walkFileTree( Paths.get( base ), new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile( Path path, BasicFileAttributes attribs ) {
        if ( path.toString().endsWith( ".java" ) )
          result.add( path.toString() );
        return FileVisitResult.CONTINUE;
      }
    } );
    return result.toArray( new String[result.size()] );
  }
}

class LineCountingVisitor extends TreeScanner<Void, Void> {
  final List<Integer> numberOfLines = new ArrayList<Integer>( 2048 );

  @Override
  public Void visitMethod( MethodTree node, Void p ) {
    if ( node.getBody() != null ) {
      int lines = new StringTokenizer( node.getBody().toString(), "\n" ).countTokens() - 1 /* { */ - 1 /* } */;
      if ( lines != 0 ) // ignore empty bodies
        numberOfLines.add( lines );
    }
    return super.visitMethod( node, p );
  }
}

Result:

DoubleSummaryStatistics{count=84695, sum=576427,000000, min=1,000000, average=6,805915, max=1716,000000}

Exercise for the readers:

  • Analyse different open source products and post the results here.
  • Generate a SVG with the lines of code.
  • Change the calculation so we not only get the arithmetic mean but also the geometric and harmonic mean.
  • Sort the result by package, are there differences?
  • Recognize the @since Javadoc tag and try to find out if the number of lines change over time.
  • How about the line size?

number-of-lines-jdk

Avatar verabschiedet sich

Mal wieder geht ein Java-Oracle-Projekt den Bach runter, dieses mal Avatar/Avatar.js (Quelle https://blogs.oracle.com/theaquarium/entry/project_avatar_update).

https://avatar-js.java.net/, https://avatar.java.net/

Avatar ist/war eine Art Node.js Implementierung in JavaScript auf der JVM.

http://nodyn.io/ ist eine spannende Altarnative, läuft aber auf einer eigenen JavaScript-Umgebung namens DynJS, nicht auf Nashorn.

Offtopic: .NET/C# nun auch Open-Source

Vor einiger Zeit hat MS begonnen die Quellen ihrer Laufzeitumgebung, Bibliotheken und Compiler auf ein Git-Repository (sync mit NET Framework TFS Server innerhalb von Microsoft) zu setzen – ein großartiger Zug! Alles steht unter der MIT-Lizenz.

Zum Einlesen:

Ich freue mich auf die spannenden Entwicklungen aus dem CLR-Lager. Hätte MS diesen Zug schon 10 Jahre früher gemacht, könnte ich gar nicht ausmalen, wie es mit der Verbreitung von Java heute aussehen würde.