OpenJDK unter Ubuntu bauen
Kategorie Software Engineering | Keine Kommentare »
Ist es eigentlich möglich eine aktuelle Java Version selbst zu bauen? Um das herauszufinden, habe ich einen Versuch unternommen und die aktuelle Entwicklungsversion des OpenJDK auf meinem Ubuntu Rechner gebaut. Das ging leichter als erwartet…
Anforderungen Bauprozess OpenJDK
Das OpenJDK ist die Referenzimplementierung von Java und der Java Virtual Machine (JVM). Das Projekt stellt sowohl die Ausführungsumgebung (JVM), die Standardbibliothek (Java SE) und den Java Compiler (javac) bereit.
Um die Entwicklungsversion zu bauen, benötigt man:
- eine große Menge von Entwicklungsbibliotheken und Tools
- ein lauffähiges JDK, genannt Boot JDK
Die Entwicklungsbibliotheken und Tools kann man unter Ubuntu über folgenden Befehl installieren:
sudo apt-get install mercurial build-essential libasound2-dev libcups2-dev libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev
Das Boot JDK wird während des Bauprozess genutzt, um in Java implementierte Bestandteile zu übersetzen. Laut Build Doku darf das Boot JDK nicht älter als die Vorgängerversion sein, die man bauen möchte. Möchte man also aktuell OpenJDK 11 bauen, bräuchte man mindestens ein JDK 10 als Boot JDK. Der Bauprozess sieht das allerdings nicht so eng, sondern erlaubt beim JDK 11 ein Boot JDK der Versionen 9-11. Ein OpenJDK 9 lässt sich unter Ubuntu folgendermaßen installieren:
sudo apt-get install openjdk-9-jdk
Nach der Installation ist JDK 9 das Default JDK unter Ubuntu. Man kann sich die Liste der installierten JDKs anzeigen lassen mittels:
sudo update-java-alternatives --list
Ein Wechsel auf ein anderes JDK geht folgendermaßen:
sudo update-java-alternatives --set /usr/lib/jvm/java-1.8.0-openjdk-amd64
Sind alle Tools und Entwicklungsbibliotheken installiert, kann man den Bau konfigurieren.
OpenJDK Bau konfigurieren
Zunächst muss der Quellcode des OpenJDK her. OpenJDK verwendet Mercurial zur Versionsverwaltung. Die aktuelle Entwicklungsversion liegt im Repo jdk/jdk. Dieses lässt sich folgendermaßen clonen:
hg clone http://hg.openjdk.java.net/jdk/jdk
Das Clonen dauert einige Zeit. Aktuell ist das Repo 1,6GB groß. Das Ergebnis liegt anschließend im Unterordner jdk/. Im Gegensatz zu älteren Anleitungen wird die Mercurial Extension HG Forest nicht mehr benötigt.
Anschließend muss der Bau konfiguriert werden. In den Standardeinstellungen führt jede Warnung zu einem Abbruch der Kompilierung. Dies ist für offizielle Releases sicher eine sinnvolle Einstellung, aber während der Entwicklung nicht unbedingt praktikabel. Aktuell würde die Kompilierung unter Ubuntu scheitern, weil einige GLIB Funktionen als veraltet markiert sind aber vom OpenJDK immer noch verwendet werden. Deshalb habe ich dieses strikte Verhalten deaktiviert.
bash configure --disable-warnings-as-errors
Sollte der Konfigurationsschritt mit einem Fehler abbrechen, fehlt vermutlich noch eine Bibliothek oder ein Tool. Glücklicherweise liefert das Skript in solch einem Fall immer gleich den Befehl, um die fehlende Abhängigkeit zu installieren. Falls was fehlt, wäre ich über einen Hinweis in den Kommentaren dankbar, dann kann ich es oben in das apt-get Beispiel gleich mit aufnehmen!
Ist die Konfiguration erfolgreich, kann mit dem eigentlichen Bau begonnen werden. Gab es einen Fehler oder möchte man sich nochmal die Ausgabe des Konfigurationsschritts anschauen, findet man die entsprechende Logdatei im Unterordner build/*/*.log.
OpenJDK kompilieren
Den Bau des OpenJDKs stößt man über folgendes Kommando an:
make images
Danach kann man sich erst mal einen Kaffee holen, denn es wird einige Zeit dauern. Gibt es einen Fehler, hilft nur eine Websuche. Vermutlich ist man nicht der Erste mit dem jeweiligen Problem.
Eigenes OpenJDK testen
Das fertige JDK liegt ebenfalls im Unterordner build/. Die Ausgabe der Versionsnummer ist ein erster möglicher Test:
build/linux-x86_64-normal-server-release/jdk/bin/javac -version
build/linux-x86_64-normal-server-release/jdk/bin/java -version
Noch cooler ist es natürlich, die seit Java 9 enthaltene JShell zu starten und die aktuellsten Sprachfeatures zu testen :-)
seb@ubuntu:~$ build/linux-x86_64-normal-server-release/jdk/bin/jshell
| Welcome to JShell -- Version 11-internal
| For an introduction type: /help intro
jshell> var s = new String("Hello World!")
s ==> "Hello World!"
jshell> System.out.println(s)
Hello World!
Zugegeben, dieses Beispiel nutzt nur Java 10, aber die für Java 11 geplanten Neuerungen sind per JShell kaum sinnvoll nutzbar.