¿Qué es la marca --release en el compilador de Java 9?

Respuestas:

106

No exactamente.

JEP 247: Compile for Old Platform Versions define esta nueva opción de línea de comandos--release:

Definimos una nueva opción de línea de comandos --release, que configura automáticamente el compilador para producir archivos de clase que se vincularán con una implementación de la versión de plataforma dada. Para las plataformas predefinidas en javac, --release Nes equivalente a-source N -target N -bootclasspath <bootclasspath-from-N> . (énfasis mío)

Entonces no, no es equivalente a -source N -target N. El motivo de esta adición se indica en la sección "Motivación":

javacproporciona dos opciones de línea de comando, -sourcey -target, que se pueden usar para seleccionar la versión del lenguaje Java aceptada por el compilador y la versión de los archivos de clase que produce, respectivamente. Sin embargo, de forma predeterminada, se javaccompila con la versión más reciente de las API de la plataforma. Por lo tanto, el programa compilado puede usar accidentalmente API que solo están disponibles en la versión actual de la plataforma. Dichos programas no pueden ejecutarse en versiones anteriores de la plataforma, independientemente de los valores pasados ​​a -sourcey -target. opciones. Este es un problema de usabilidad a largo plazo, ya que los usuarios esperan que al usar estas opciones obtengan archivos de clase que puedan ejecutarse en la versión de plataforma especificada.

En resumen, especificar las opciones de origen y destino no es suficiente para la compilación cruzada. Debido a que javac, de forma predeterminada, se compila con la API de la plataforma más reciente, no se puede garantizar que se ejecuten en versiones anteriores. También debe especificar la -bootclasspathopción correspondiente a la versión anterior para realizar una compilación cruzada correctamente. Esto incluiría la versión correcta de la API para compilar y permitir la ejecución en una versión anterior. Dado que a menudo se olvidaba, se decidió agregar una opción de línea de comando que hizo todo lo necesario para realizar una compilación cruzada correcta.

Más información en la lista de correo y Oracle Docs . El error original se archivó aquí . Tenga en cuenta que desde la integración de esta opción, las compilaciones de JDK se incluyen con descripciones de las API de la plataforma de versiones anteriores, mencionadas en la sección "Riesgos y suposiciones". Eso significa que no necesita la versión anterior instalada en su máquina para que funcione la compilación cruzada.

Andrew Li
fuente
una duda, ¿sería posible usar características de jdk 9-11 en el código y aún se ejecuta en Java Runtime 8?
Cristiano
No, no estarían presentes en el binario jre 8
Rogue
¿Qué opinan de "Plataforma API"? ¿Hay algo a nivel de código de bytes? o algo relacionado con la plataforma x86 subyacente o las API del sistema operativo?
Jose Cifuentes
2
@JoseCifuentes, "API de plataforma" aquí se le da a la API de JDK, su versión, sin el --releaseindicador, se inferiría del JDK usado para compilar, que generalmente difiere del JDK al que se dirige usando -sourcey -target. Esto puede morderlo en caso de que use clases / métodos introducidos en nunca JDK y luego en el que apunta. Esto es muy sutil en caso de que el compilador elija una sobrecarga de método que se agregó en una versión posterior sobre la anterior que pretendía, rompiendo así silenciosamente la compatibilidad binaria.
Oliver Gondža
30

--release Xes más que un acceso directo a -source X -target Xporque -sourcey -targetno son suficientes para compilar de forma segura en una versión anterior. También necesita establecer una -bootclasspathbandera que debe corresponder a la versión anterior (y esta bandera a menudo se olvida). Así, en Java 9 hicieron una sola --releasebandera que es un sustituto de tres banderas: -source, -targety -bootclasspath.

Entonces, este es un ejemplo de compilación en Java 1.7:

javac --release 7 <source files>

Tenga en cuenta que ni siquiera necesita tener JDK 7 instalado en su computadora. JDK 9 ya contiene la información necesaria para evitar que se vincule accidentalmente a símbolos que no existían en JDK 7.

ZhekaKozlov
fuente