Wird bei den JREs 9, 10, 11+ ueberhaupt noch Bytecode ausgefuehrt..?

sirbender

Top Contributor
Hallo,

mit Java9 wurden die Module eingefuehrt. Wenn man sich OpenJDK9 runterlaedt sieht man einen neuen Ordner jmods mit den Modulen, mit den Dateiendungen "jmod". Dies sind gepimpte jar Dateien.

Mit jlink kann man nun eigene JREs erstellen wo nur noch die Module dabei sind die man braucht. Ich hab das mal getestet. Lustigerweise werden gar keine Module (jmod-Dateien, a.k.a. jars) dazugepackt. Lediglich .so Dateien findet man.

Meine Frage: wird gar kein Bytecode mehr ausgefuehrt? Ist bereits alles vorkompiliert als .so Dateien?

Gibt es eine ausfuehrliche Beschreibung diese Aenderungen und auch vielleicht eine Erklaerung wie das nun alles waehrend der Laufzeit umgesetzt wird? Hotspot optimiert ja eigentlich die Ausfuehrung von Bytecode? Oder kann der auch die .so Dateien optimieren?

Ich blicke echt nicht mehr durch.
 
Ja, auch eine per jlink gebaute Anwendung enthält Bytecode, der ganz normal durch die JVM (die ja in der per jlink gebauten "Distribution" enthalten ist) ausgeführt wird.
Die Module der Anwendung, also die Abhängigkeiten und das Anwendungs-Modul selbst, werden in der Datei <distfolder>/lib/modules gespeichert. <distfolder> ist hierbei der Ordner, der als --output <distfolder> Argument beim Aufruf von jlink angegeben wurde. Bei der modules Datei handelt es sich nicht mehr um eine Datei im ZIP-Format.
 
Bei der modules Datei handelt es sich nicht mehr um eine Datei im ZIP-Format.

'modules' ist nicht mehr im ZIP Format aber es ist dennoch praktisch der Inhalt der jmod-Dateien - nur halt irgendwie aneinandergepappt? Was fuer ein Format hat 'modules'? Irgendeine undokumentierte Oracle-Eigenkreation? Kann ich die Datei irgendwie oeffnen und anschauen?
 
So, jetzt ein bischen mehr Klarheit. Trotzdem auch noch viel Verwirrung. Man kann die 'modules' Datei auslesen. Ich habe den jlink build abhaengig gemacht von jdk.jshell und jdk.zipfs. In der resultierenden 'modules'-Datei lese ich dann folgende Module aus:

/modules/java.base
/modules/java.compiler
/modules/java.logging
/modules/java.prefs
/modules/java.xml
/modules/jdk.attach
/modules/jdk.compiler
/modules/jdk.internal.ed
/modules/jdk.internal.jvmstat
/modules/jdk.internal.le
/modules/jdk.internal.opt
/modules/jdk.jdi
/modules/jdk.jdwp.agent
/modules/jdk.jshell
/modules/jdk.zipfs

Nur laut Javadoc sollten eigenlich weniger Module reingepackt werden:
https://docs.oracle.com/javase/10/docs/api/jdk.jshell-summary.html
https://docs.oracle.com/javase/10/docs/api/jdk.zipfs-summary.html

Wie ist das zu erklaeren? jdk.jshell und jdk.zipfs haben doch gar nicht so viele Abhaengigkeiten wie oben aufgelistet, oder sind das irgendwie impliziete Abhaengigkeiten die nicht im Javadoc gelistet sind?

Die jlink modules-Datei des Minimal-JRE (nur --add-modules java.base) enthaelt wenn man sie ausliest uebrigens wirklich nur java.base
 
Der Schuldige ist jdk.jshell.jmod. Wenn du dir dieses Modul mal anguckst, dann siehst du, dass es sehr viel mehr Modul-Abhängigkeiten hat als nur die in der JavaDoc angegebenen. Darüber und über deren jeweilige Abhängigkeiten kommt die lange Liste der Module zustande.

Wenn du dir z.B. mal die darin enthaltene module-info.class extrahierst und mit javap anzeigst, siehst du:
Code:
Compiled from "module-info.java"
module jdk.jshell@10.0.1 {
  requires java.base;
  requires java.logging;
  requires jdk.compiler;
  requires jdk.internal.ed;
  requires jdk.internal.le;
  requires jdk.internal.opt;
  requires transitive java.compiler;
  requires transitive java.prefs;
  requires transitive jdk.jdi;
  exports jdk.jshell;
  exports jdk.jshell.execution;
  exports jdk.jshell.spi;
  exports jdk.jshell.tool;
  uses jdk.jshell.spi.ExecutionControlProvider;
  uses jdk.internal.editor.spi.BuildInEditorProvider;
  provides  javax.tools.Tool with
    jdk.internal.jshell.tool.JShellToolProvider;
  provides  jdk.jshell.spi.ExecutionControlProvider with
    jdk.jshell.execution.JdiExecutionControlProvider,
    jdk.jshell.execution.LocalExecutionControlProvider,
    jdk.jshell.execution.FailOverExecutionControlProvider;
}
 
Danke. Da machen die Javadocs extra einen Abhaengigkeitsgraphen und darunter auch textuell die Dependencies, aber dann fehlt da ein Haufen.

Weisst du nach welchen Regeln da gefiltert wurde? Alles "internal" ?
 
Wenn ich's richtig sehe, sind das alles jdk.internal.*, die im Javadoc nicht auftauchen und deshalb auch nicht im Dependency-Graph zu sehen sind.
 

Zurück
Oben