Especificación de la versión de Java en maven: diferencias entre propiedades y complemento del compilador
No tengo mucha experiencia con Maven y mientras experimentaba con un proyecto de varios módulos comencé a preguntarme cómo puedo especificar la versión de Java para todos mis módulos secundarios en el pom principal de Maven. Hasta hoy estaba usando solo:
<properties>
<java.version>1.8</java.version>
</properties>
...pero al investigar descubrí que también puedes especificar la versión de Java en el complemento del compilador Maven, así:
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
Y luego incluya esto en la etiqueta de administración de complementos para permitir el uso de pompones secundarios. Entonces la primera pregunta es esta:
¿Cuáles son las diferencias entre configurar la versión de Java en las propiedades y en el complemento del compilador Maven?
No pude encontrar una respuesta clara, pero en el proceso de investigación descubrí que también puedes especificar la versión de Java de esta manera:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
...lo que sugiere que el complemento del compilador está ahí incluso si no lo declaro explícitamente. Ejecución de mvn package
salidas con
maven-compiler-plugin:3.1:compile (default-compile) @ testproj ---
...y algunos otros complementos que no declaré.
Entonces, ¿esos complementos son una parte oculta y predeterminada de Maven pom? ¿Existe alguna diferencia entre configurar el origen/destino en las propiedades y en el elemento de configuración del complemento Maven?
Algunas otras preguntas son: ¿qué forma se debe utilizar (y cuándo si no son iguales)? ¿Cuál es mejor para proyectos de varios módulos y qué sucede si la versión de Java especificada en pom es diferente a la versión indicada JAVA_HOME
?
¿Cómo especificar la versión JDK?
Utilice cualquiera de las tres formas: (1) función Spring Boot o utilice el complemento del compilador Maven con (2) source
& target
o (3) con release
.
Bota de primavera
1.8<java.version>
no se hace referencia en la documentación de Maven.
Es una especificidad de Spring Boot.
Permite configurar la versión de Java de origen y de destino con la misma versión, como esta, para especificar Java 1.8 para ambas:
Siéntete libre de usarlo si usas Spring Boot.
maven-compiler-plugin
con source
&target
- El uso de propiedades
maven-compiler-plugin
omaven.compiler.source
/maven.compiler.target
es equivalente.
Eso es de hecho:
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
es equivalente a :
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
de acuerdo con la documentación de Maven del complemento del compilador
ya que <source>
y los <target>
elementos en la configuración del compilador usan las propiedades maven.compiler.source
y maven.compiler.target
si están definidas.
fuente
El
-source
argumento para el compilador de Java.
NOTA : Desde 3.8.0, el valor predeterminado ha cambiado de 1,5 a 1,6. Desde 3.9.0, el valor predeterminado ha cambiado de 1,6 a 1,7.
El valor predeterminado es: 1,7.
La propiedad del usuario es:maven.compiler.source
.
objetivo
El
-target
argumento para el compilador de Java.
NOTA : Desde 3.8.0, el valor predeterminado ha cambiado de 1,5 a 1,6. Desde 3.9.0, el valor predeterminado ha cambiado de 1,6 a 1,7.
El valor predeterminado es:1.6
.
La propiedad del usuario es:maven.compiler.target
.
Acerca de los valores predeterminados para source
y target
, tenga en cuenta que
desde 3.8.0
el compilador maven, los valores predeterminados han cambiado de 1.5
a1.6
.
maven-compiler-plugin
con release
en lugar de source
&target
El complemento maven-compiler
org.apache.maven.plugins maven-compiler-plugin 3.8.0 93.6
y las versiones posteriores proporcionan una nueva forma:
También podrías declarar simplemente:
<properties>
<maven.compiler.release>9</maven.compiler.release>
</properties>
Pero en este momento no funcionará porque la maven-compiler-plugin
versión predeterminada que utiliza no depende de una versión lo suficientemente reciente.
El release
argumento de Maven transmite release
: una nueva opción estándar de JVM que podríamos pasar desde Java 9:
Se compila con la API pública, compatible y documentada para una versión de VM específica.
De esta manera proporciona una forma estándar de especificar la misma versión para las opciones source
, target
y bootstrap
JVM.
Tenga en cuenta que especificar bootstrap
es una buena práctica para compilaciones cruzadas y no estará de más si tampoco realiza compilaciones cruzadas.
¿Cuál es la mejor manera de especificar la versión JDK?
La primera forma ( <java.version>
) está permitida solo si usa Spring Boot.
Para Java 8 y versiones anteriores:
Acerca de las otras dos formas: valorando las propiedades maven.compiler.source
/ o usando , puedes usar una u otra. No cambia nada en los hechos ya que finalmente las dos soluciones se basan en las mismas propiedades y el mismo mecanismo: el complemento del compilador central de Maven.maven.compiler.target
maven-compiler-plugin
Bueno, si no necesita especificar otras propiedades o comportamientos además de las versiones de Java en el complemento del compilador, usarlo de esta manera tiene más sentido ya que es más conciso:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
De Java 9:
El release
argumento (tercer punto) es una forma de considerar seriamente si desea utilizar la misma versión para el origen y el destino.
¿Qué sucede si la versión difiere entre el JDK en JAVA_HOME y el especificado en pom.xml?
No es un problema si el JDK al que hace referencia JAVA_HOME
es compatible con la versión especificada en el pom, pero para garantizar una mejor compatibilidad de compilación cruzada, piense en agregar la bootstrap
opción JVM con como valor la ruta de rt.jar
la target
versión.
Una cosa importante a considerar es que la versión source
y target
en la configuración de Maven no debe ser superior a la versión de JDK a la que hace referencia el archivo JAVA_HOME
.
Una versión anterior del JDK no puede compilarse con una versión más reciente porque no conoce su especificación.
Para obtener información sobre las versiones de origen, de destino y de lanzamiento compatibles según el JDK utilizado, consulte la compilación de Java: versiones compatibles de origen, de destino y de lanzamiento .
¿Cómo manejar el caso de que el JDK al que hace referencia JAVA_HOME no sea compatible con las versiones de destino y/o fuente de Java especificadas en el pom?
Por ejemplo, si se JAVA_HOME
refiere a un JDK 1.7 y especifica un JDK 1.8 como origen y destino en la configuración del compilador de su pom.xml, será un problema porque, como se explicó, el JDK 1.7 no sabe cómo compilar con .
Desde su punto de vista, es una versión JDK desconocida ya que fue lanzada después.
En este caso, debes configurar el complemento del compilador Maven para especificar el JDK de esta manera:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerVersion>1.8</compilerVersion>
<fork>true</fork>
<executable>D:\jdk1.8\bin\javac</executable>
</configuration>
</plugin>
Podría tener más detalles en ejemplos con el complemento del compilador maven .
No se pregunta, pero los casos en los que puede resultar más complicado es cuando se especifica el origen pero no el destino. Puede utilizar una versión diferente en el destino según la versión de origen. Las reglas son particulares: puedes leer sobre ellas en la parte Opciones de compilación cruzada .
¿Por qué se rastrea el complemento del compilador en la salida durante la ejecución del package
objetivo de Maven incluso si no lo especifica en pom.xml?
Para compilar su código y, en general, realizar todas las tareas necesarias para lograr el objetivo de Maven, Maven necesita herramientas. Por lo tanto, utiliza complementos principales de Maven (reconoce un complemento principal de Maven por su groupId
:) org.apache.maven.plugins
para realizar las tareas requeridas: complemento compilador para compilar clases, complemento de prueba para ejecutar pruebas, etc. Entonces, incluso si no lo hace Declare estos complementos, están vinculados a la ejecución del ciclo de vida de Maven.
En el directorio raíz de su proyecto Maven, puede ejecutar el comando: mvn help:effective-pom
para utilizar el pom final de manera efectiva. Podrás ver entre otra información, plugins adjuntos de Maven (especificados o no en tu pom.xml), con la versión utilizada, su configuración y los objetivos ejecutados para cada fase del ciclo de vida.
En el resultado del mvn help:effective-pom
comando, puede ver la declaración de estos complementos principales en el <build><plugins>
elemento, por ejemplo:
...
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>default-testResources</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goals>
</execution>
<execution>
<id>default-resources</id>
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
...
Puede tener más información al respecto en la introducción del ciclo de vida de Maven en la documentación de Maven .
Sin embargo, puedes declarar estos complementos cuando quieras configurarlos con otros valores como valores predeterminados (por ejemplo, lo hiciste cuando declaraste el complemento maven-compiler en tu pom.xml para ajustar la versión de JDK a usar) o cuando Desea agregar algunas ejecuciones de complementos que no se utilizan de forma predeterminada en el ciclo de vida de Maven.
Ninguna de las soluciones anteriores funcionó para mí de inmediato. Entonces seguí estos pasos:
- Añadir
pom.xml:
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
Vaya a
Project Properties
>Java Build Path
y luego elimine la biblioteca del sistema JRE que apunta aJRE1.5
.Force actualizó el proyecto.
¡Los pasos a continuación funcionan para mí a las mil maravillas! así que pensado para compartir con todos.
Estas son las líneas que agregué en el archivo pom.xml para trabajar con un proyecto básico. Estoy usando Java 12 (puedes reemplazar el tuyo 11, 10, 1.8, etc.).
<properties>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>12</release>
</configuration>
</plugin>
</plugins>
</build>
Después de cambiar el archivo pom, vuelva a cargar su proyecto para que IDE pueda descargar/obtener el complemento al proyecto. (Para IntelijIDEA: haga clic derecho en pom.xml -> Ir a maven -> Recargar proyecto).
asegúrese de configurar también la versión deseada en su IDE.
si está utilizando la compilación IntelliJ idea maven.