pom plugin force compiler java maven maven-3 maven-compiler-plugin

java - force - maven-compiler-plugin pom



Especificación de la versión de Java en Maven: diferencias entre las propiedades y el complemento del compilador (3)

No tengo mucha experiencia con Maven y, mientras experimentaba con proyectos de varios módulos, comencé a preguntarme cómo puedo especificar la versión de Java para todos mis módulos secundarios en Maven Pom. 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 envuelva esto en la etiqueta de administración de complementos para permitir el uso de esto por parte de niños. Entonces, la primera pregunta es ¿cuáles son las diferencias entre la configuración de 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 puede 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. Ejecutar salidas de paquete mvn con

maven-compiler-plugin:3.1:compile (default-compile) @ testproj ---

y algunos otros complementos que no he declarado. Entonces, ¿esos complementos son parte oculta y predeterminada de Maven Pom? ¿Hay alguna diferencia entre establecer 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 el mejor para un proyecto de varios módulos y qué sucede si la versión de Java especificada en Pom es diferente de la versión apuntada en JAVA_HOME?


Considere la alternativa:

<properties> <javac.src.version>1.8</javac.src.version> <javac.target.version>1.8</javac.target.version> </properties>

Debería ser lo mismo de maven.compiler.source/maven.compiler.target pero la solución anterior funciona para mí, de lo contrario, la segunda obtiene la especificación principal (tengo una matrioska de .pom)


Ninguna de las soluciones anteriores me funcionó de inmediato. Entonces hice lo siguiente:

  1. Adicional

    <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties>

    en pom.xml

  2. Fui a Project Properties > Java Build Path , luego JRE1.5 Biblioteca del sistema JRE que apuntaba a JRE1.5 .

  3. Force actualizó el proyecto.


¿Cómo especificar la versión JDK?

1) <java.version> no está referenciado en la documentación de Maven.
Es una especificidad de arranque de primavera.
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 ambos:

<properties> <java.version>1.8</java.version> </properties>

Siéntase libre de usarlo si usa Spring Boot.

2) Usando las propiedades maven-compiler-plugin o maven.compiler.source / maven.compiler.target para especificar el source y el target son equivalentes.

<plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins>

y

<properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>

son equivalentes según la documentación de Maven del complemento del compilador ya que los elementos <source> y <target> en la configuración del compilador usan las propiedades maven.compiler.source y maven.compiler.target si están definidos.

source

El argumento -source para el compilador de Java.
El valor predeterminado es: 1.6 .
La propiedad del usuario es: maven.compiler.source .

target

El argumento -target para el compilador de Java.
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 el 3.8.0 del compilador maven, los valores predeterminados han cambiado de 1.5 a 1.6 .

3) Maven-compiler-plugin 3.6 y versiones posteriores proporcionan una nueva forma:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>9</release> </configuration> </plugin>

También podría declarar solo:

<properties> <maven.compiler.release>9</maven.compiler.release> </properties>

Pero en este momento no funcionará, ya que la versión predeterminada de maven-compiler-plugin que usa no se basa en una versión lo suficientemente reciente.

El argumento de release Maven transmite release : una nueva opción estándar de JVM que podríamos pasar de Java 9:

Compila contra la API pública, compatible y documentada para una versión de VM específica.

De esta forma, se proporciona una forma estándar de especificar la misma versión para las opciones JVM de source , target y bootstrap .
Tenga en cuenta que especificar el bootstrap es una buena práctica para las compilaciones cruzadas y no le hará daño 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 a continuación:

Acerca de las otras dos formas: valorando las propiedades maven.compiler.source / maven.compiler.target o usando el maven-compiler-plugin , puede usar uno u otro. No cambia nada en los hechos, ya que finalmente las dos soluciones se basan en las mismas propiedades y el mismo mecanismo: el complemento compilador maven core.

Bueno, si no necesita especificar otras propiedades o comportamientos que las versiones de Java en el complemento del compilador, usar este método 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>

Desde Java 9:

El argumento de release (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 cuál se especifica en el 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 opción JVM de bootstrap con como valor la ruta del rt.jar del target versión.

Una cosa importante a considerar es que la versión de source y de target en la configuración de Maven no debe ser superior a la versión JDK a la que hace referencia JAVA_HOME .
Una versión anterior del JDK no puede compilarse con una versión más reciente ya que no conoce su especificación.

Para obtener información sobre las versiones compatibles de origen, destino y lanzamiento de acuerdo con el JDK utilizado, consulte la compilación de Java: versiones compatibles de origen, destino y lanzamiento .

¿Cómo manejar el caso de JDK al que hace referencia JAVA_HOME no es compatible con las versiones de destino y / o fuente de Java especificadas en el pom?

Por ejemplo, si su JAVA_HOME refiere a un JDK 1.7 y especifica un JDK 1.8 como fuente 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 desconocida de JDK ya que fue lanzada después.
En este caso, debe 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 compilador maven .

No se pregunta, pero los casos en que eso puede ser más complicado es cuando se especifica el origen pero no el destino. Puede usar una versión diferente en el destino de acuerdo con la versión de origen. Las reglas son particulares: puede leer sobre ellas en la parte Opciones de compilación cruzada .

¿Por qué el complemento del compilador se rastrea en la salida en la ejecución del objetivo del package Maven incluso si no lo especifica en el pom.xml?

Para compilar su código y, en general, para realizar todas las tareas necesarias para un objetivo de Maven, Maven necesita herramientas. Por lo tanto, utiliza los complementos principales de Maven (reconoce un complemento principal de Maven por su groupId : org.apache.maven.plugins ) para realizar las tareas requeridas: complemento del compilador para compilar clases, complemento de prueba para ejecutar pruebas, y así para ... Entonces, incluso si no declara estos complementos, están obligados 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 obtener el pom final de manera efectiva. Puede ver, entre otra información, los complementos adjuntos de Maven (especificados o no en su 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 , puede ver la declaración de estos complementos principales en el elemento <build><plugins> , 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 obtener más información al respecto en la introducción del ciclo de vida de Maven en la documentación de Maven .

Sin embargo, puede declarar estos complementos cuando desee configurarlos con otros valores como valores predeterminados (por ejemplo, lo hizo cuando declaró el complemento del compilador maven en su pom.xml para ajustar la versión JDK a usar) o cuando desea agregar algunas ejecuciones de complementos que no se usan por defecto en el ciclo de vida de Maven.