2011-02-25 22 views
19

He configurado mi archivo pom para pedirle a Maven que compile mi código fuente para que sea compatible con la versión 1.5 utilizando los parámetros de configuración source y target. Aquí está mi pom:Establecer el -source y -target del compilador de Java con Maven - no funciona

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com</groupId> 
    <artifactId>user</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <name>test</name> 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <configuration> 
      <source>1.5</source> 
      <target>1.5</target> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 
</project> 

Y tengo una sencilla clase principal como esto:

package com.user; 
public class Test 
{ 
    public static void main(String[] argv) 
    { 
     System.out.println("".isEmpty()); 
    } 
} 

String#isEmpty() se introdujo desde Java 1.6. Sin embargo, la compilación de mi código con mvn compile funciona, mientras que esperaba que fallara porque he configurado Maven para compilar mi código para Java 1.5 y String#isEmpty se introdujo en Java 1.6. ¿Alguien podría sugerir lo que podría haber hecho mal? ¿Cuál es la forma correcta de forzar a Maven a usar una versión de Java particular al compilar?

Para información, estoy usando Apache Maven 2.2.1 y javac 1.6.0_19.

Gracias.

Respuesta

28

De la nota en la parte inferior de la compiler-plugin page:

mero establecimiento de la opción de destino no garantiza que el código se ejecuta en realidad un JRE con la versión especificada. El inconveniente es el uso involuntario de las API que solo existen en JRE posteriores que harían que tu código fallara en tiempo de ejecución con un error de enlace. Para evitar este problema, puede configurar ya sea de ruta de clases de arranque del compilador para que coincida con el JRE de destino o utilice el animal Sniffer Maven Plugin para verificar su código no utiliza las API no deseados

Esto significa que aunque se está generando 1,5 -nivel de código de bytes, todavía puede (involuntariamente) llamar a un método 1.6 API. Para marcar estas llamadas API invalidas, use el complemento que mencionan.

+1

Esa es una gran solución, pero desafortunadamente no maneja algunas otras incompatibilidades API, como la implementación parcial de la interfaz. Si no implementa el método remove() de Iterator, compilará bajo java 8 debido a la palabra clave 'default' en la interfaz, pero no compilará bajo java 7. Y este plugin sniffer no captará eso porque no es solo un método llamada. – Innokenty

+0

Aquí hay una guía oficial sobre cómo usar Animal Sniffer y por qué: https://maven.apache.org/guides/mini/guide-building-jdk14-on-jdk15.html – Innokenty

8

Necesita compilar con una versión inferior de Java si no desea que encuentre String.isEmpty(). El nivel de fuente controla las características de nivel de idioma que puede y no puede usar, como @Override en las interfaces que requieren compilación con el nivel de origen 1.6. El nivel objetivo controla la compatibilidad del bytecode que produce la compilación. Ninguno de los dos tiene nada que ver con las API disponibles ... todo está basado en el classpath que usas al compilar, que en tu caso incluye Java 1.6.

+0

Además, asegúrese de que tanto CLASSPATH como JAVA_HOME las variables apuntan a la versión correcta de JDK. (Me colgué de este problema, y ​​mi JAVA_HOME apuntaba a Java 6 cuando necesitaba compilar a 5.) – hotshot309

Cuestiones relacionadas