Was ist das Flag --release im Java 9-Compiler?

Antworten:

106

Nicht genau.

JEP 247: Kompilieren für ältere Plattformversionen definiert diese neue Befehlszeilenoption--release:

Wir haben eine neue Befehlszeilenoption definiert --release, die den Compiler automatisch so konfiguriert, dass Klassendateien erstellt werden, die mit einer Implementierung der angegebenen Plattformversion verknüpft werden. Für die Plattformen in vordefiniert javac, --release Nentspricht-source N -target N -bootclasspath <bootclasspath-from-N> . (Hervorhebung von mir)

Also nein, es ist nicht gleichbedeutend mit -source N -target N. Der Grund für diesen Zusatz ist im Abschnitt "Motivation" angegeben:

javacbietet zwei Befehlszeilenoptionen -sourceund -target, mit denen die vom Compiler akzeptierte Version der Java-Sprache und die Version der von ihm erstellten Klassendateien ausgewählt werden können. Standardmäßig wird jedoch mit javacder neuesten Version der Plattform-APIs kompiliert. Das kompilierte Programm kann daher versehentlich APIs verwenden, die nur in der aktuellen Version der Plattform verfügbar sind. Solche Programme können auf ältere Versionen der Plattform nicht ausgeführt, unabhängig von den Werten auf den übergebenen -sourceund -target. Optionen. Dies ist ein langfristiger Problemfaktor für die Benutzerfreundlichkeit, da Benutzer erwarten, dass sie durch Verwendung dieser Optionen Klassendateien erhalten, die auf der angegebenen Plattformversion ausgeführt werden können.

Kurz gesagt, die Angabe der Quell- und Zieloptionen reicht für die Kreuzkompilierung nicht aus. Da javacstandardmäßig Kompilierungen mit den neuesten Plattform-APIs durchgeführt werden, kann nicht garantiert werden, dass sie auf älteren Versionen ausgeführt werden. Sie müssen auch die -bootclasspathOption angeben, die der älteren Version entspricht, um die Kompilierung korrekt durchzuführen. Dies würde die richtige API-Version enthalten, mit der kompiliert werden kann, und die Ausführung auf einer älteren Version ermöglichen. Da es sehr oft vergessen wurde, wurde beschlossen, eine Befehlszeilenoption hinzuzufügen, die alle notwendigen Schritte zum korrekten Cross-Kompilieren ausführte.

Lesen Sie weiter in der Mailingliste und in Oracle Docs . Der ursprüngliche Fehler wurde hier abgelegt . Beachten Sie, dass JDK-Builds seit der Integration dieser Option mit Beschreibungen der Plattform-APIs älterer Versionen gebündelt sind, die im Abschnitt "Risiken und Annahmen" aufgeführt sind. Das bedeutet, dass Sie die ältere Version nicht auf Ihrem Computer installiert haben müssen, damit die Cross-Kompilierung funktioniert.

Andrew Li
quelle
Ein Zweifel, wäre es möglich, Funktionen von JDK 9-11 im Code zu verwenden und es läuft immer noch auf Java Runtime 8?
Cristiano
Nein, sie wären nicht in der jre 8-Binärdatei vorhanden
Rogue
Was macht ihr Männer von "Platform API"? Ist etwas auf Bytecode-Ebene? oder etwas im Zusammenhang mit der zugrunde liegenden x86-Plattform oder den Betriebssystem-APIs?
Jose Cifuentes
2
@JoseCifuentes, "Plattform-API" erhält hier die JDK-API. Die Version ohne --releaseFlag wird aus dem zum Kompilieren verwendeten JDK abgeleitet, das sich im Allgemeinen von dem JDK unterscheidet, auf das Sie mit -sourceund abzielen -target. Dies kann Sie beißen, falls Sie Klassen / Methoden verwenden, die in nie JDK eingeführt wurden, als die, auf die Sie abzielen. Dies ist besonders subtil , falls der Compiler ein Verfahren wählt Überlastung , die von früheren in späteren Version über einen hinzugefügt wurde , um Ihnen so leise Binärkompatibilität brechen soll.
Oliver Gondža
30

--release Xist mehr als nur eine Verknüpfung zu, -source X -target Xweil -sourceund -targetnicht ausreicht, um sicher zu einer älteren Version zu kompilieren. Sie müssen auch ein -bootclasspathFlag setzen, das der älteren Version entsprechen muss (und dieses Flag wird oft vergessen). Also, in Java 9 machten sie eine einzige --releaseFahne , die ein Ersatz für drei Flags ist: -source, -targetund -bootclasspath.

Dies ist also ein Beispiel für das Kompilieren mit Java 1.7:

javac --release 7 <source files>

Beachten Sie, dass JDK 7 nicht einmal auf Ihrem Computer installiert sein muss. JDK 9 enthält bereits die erforderlichen Informationen, um zu verhindern, dass Sie versehentlich auf Symbole verlinken, die in JDK 7 nicht vorhanden waren.

ZhekaKozlov
quelle