Gradle, "sourceCompatibility" vs "targetCompatibility"?

130

¿Cuál es la relación / diferencia entre sourceCompatibilityy targetCompatibility? ¿Qué sucede cuando se configuran con valores diferentes?

Según la documentación de Gradle :

sourceCompatibilityes "Compatibilidad con la versión de Java que se utilizará al compilar la fuente de Java" targetCompatibilityes "Versión Java para generar clases".

Entiendo que targetCompatibilitygenerará un bytecode de Java que sea compatible con una versión específica de Java, ¿es esto un subconjunto de la funcionalidad de sourceCompatibility?

Mike Rylander
fuente

Respuestas:

80

targetCompatibilityy sourceCompatibilitymapas hacia -target releasey -source releaseen javac. El origen es básicamente el nivel del idioma de origen y el destino es el nivel del código de bytes que se genera.

Se pueden encontrar más detalles en la sección de compilación cruzada de javac .

Mate
fuente
1
El enlace anterior apunta a doc para Java 7. Me pregunto si quieres algo como docs.oracle.com/en/java/javase/11/tools/… ?
Brian Agnew
63

Tenga cuidado cuando los use; Hemos sido mordidos por personas que hacen suposiciones.

El hecho de que use sourceCompability (o targetCompatibility) de 1.5 no significa que siempre pueda compilar su código con JDK 1.6 y esperar que funcione bajo JDK 1.5. El problema son las bibliotecas disponibles.

Si su código llama a algún método que solo está disponible en JDK 1.6, aún se compilará con las diversas opciones de compatibilidad para la VM de destino. Pero cuando lo ejecutas, fallará porque el método ofensivo no está presente (obtendrás una MethodNotFoundException o ClassNotFoundException).

Por esta razón, siempre comparo la configuración de compatibilidad con la versión real de Java con la que estoy creando. Si no coinciden, fallo la construcción.

usuario1644873
fuente
44
Esta es una observación sutil, pero muy importante.
Natix
¿Cómo los comparas?
zero01alpha
¿Por qué fallas la construcción? La opción "bootstrap classpath" se ofrece solo para mitigar este problema. Siempre puedes usar el bootstrap adecuado y debería funcionar bien.
Codebender el
66
if(JavaVersion.current() != JavaVersion.VERSION_1_8) throw new GradleException("This project requires Java 8, but it's running on "+JavaVersion.current())Así es como soluciono este problema, justo al comienzo del archivo build.gradle.
Xerus
2
Desde Java 9 ahora hay una nueva javacopción --releasedestinada a abordar este problema, al permitir solo el uso de API disponible en la versión de Java especificada. Para más información, consulte stackoverflow.com/a/43103038/4653517
James Mudd el
35

sourceCompatibility = especifica que se utilizará la versión del lenguaje de programación Java para compilar archivos .java . Por ejemplo, sourceCompatibility 1.6 = especifica que la versión 1.6 del lenguaje de programación Java se utilizará para compilar archivos .java .

Por defecto sourceCompatibility = "versión de la JVM actual en uso" y targetCompatibility = sourceCompatibility

targetCompatibility = La opción asegura que los archivos de clase generados serán compatibles con las máquinas virtuales especificadas por targetCompatibility. Tenga en cuenta que en la mayoría de los casos, el valor de la opción -target es el valor de la opción -source; en ese caso, puede omitir la opción -target.

Los archivos de clase se ejecutarán en el destino especificado por targetCompatibility y en versiones posteriores, pero no en versiones anteriores de la VM

Un Jakhar
fuente
¿Cómo averiguamos cuáles está utilizando nuestro proyecto?
isJulian00
0

En mi opinión, "sourceCompatibility" se refiere a la característica que puede usar en su código fuente. Por ejemplo, si establece sourceCompatibility a 1.7, entonces no puede usar la expresión lambda, que es una nueva característica en java 8 aunque su versión jdk sea 1.8.
En cuanto a "targetCompatibility", significa en qué versión de jre se puede ejecutar el archivo de clase generado; si lo configura en 1.8, es posible que no se ejecute correctamente en jdk 1.7, pero generalmente se puede ejecutar en una versión superior de jdk.

haoyu wang
fuente
0

Estas son las banderas para el comando javac.

javac [options] [sourcefiles]

Options:
...
-source release - Specifies the version of source code accepted.
...
-target release - Generates class files for a specific VM version.
...

En otras palabras: escribe un código en una sourceversión y compila sus clases en la targetversión VM. Para ejecutarlo, por ejemplo, en otra estación de trabajo con una versión anterior de Java.

De acuerdo con: https://docs.oracle.com/en/java/javase/11/tools/javac.html

Benjamín
fuente