Especificación de la versión de Java en maven: diferencias entre propiedades y complemento del compilador

Resuelto Plebejusz asked hace 8 años • 7 respuestas

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 packagesalidas 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?

Plebejusz avatar Aug 11 '16 02:08 Plebejusz
Aceptado

¿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& targeto (3) con release.

Bota de primavera

  1. <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:

    1.8

Siéntete libre de usarlo si usas Spring Boot.

maven-compiler-plugincon source&target

  1. El uso de propiedades maven-compiler-plugino maven.compiler.source/ maven.compiler.targetes 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.sourcey maven.compiler.targetsi están definidas.

fuente

El -sourceargumento 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 -targetargumento 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 sourcey target, tenga en cuenta que desde 3.8.0el compilador maven, los valores predeterminados han cambiado de 1.5a1.6 .

maven-compiler-plugincon releaseen lugar de source&target

  1. El complemento maven-compiler 3.6y las versiones posteriores proporcionan una nueva forma:

    org.apache.maven.plugins maven-compiler-plugin 3.8.0 9

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-pluginversión predeterminada que utiliza no depende de una versión lo suficientemente reciente.

El releaseargumento 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, targety bootstrapJVM.
Tenga en cuenta que especificar bootstrapes 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.targetmaven-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 releaseargumento (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_HOMEes compatible con la versión especificada en el pom, pero para garantizar una mejor compatibilidad de compilación cruzada, piense en agregar la bootstrapopción JVM con como valor la ruta de rt.jarla targetversión.

Una cosa importante a considerar es que la versión sourcey targeten 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_HOMErefiere 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 packageobjetivo 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.pluginspara 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-pompara 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-pomcomando, 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.

davidxxx avatar Aug 10 '2016 20:08 davidxxx

Ninguna de las soluciones anteriores funcionó para mí de inmediato. Entonces seguí estos pasos:

  1. Añadirpom.xml:
<properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>
  1. Vaya a Project Properties> Java Build Pathy luego elimine la biblioteca del sistema JRE que apunta a JRE1.5.

  2. Force actualizó el proyecto.

Sen avatar Nov 20 '2018 14:11 Sen

¡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.

Shivang Agarwal avatar Apr 06 '2021 05:04 Shivang Agarwal

si está utilizando la compilación IntelliJ idea maven.

ingrese la descripción de la imagen aquí

afshar avatar Jan 24 '2022 06:01 afshar