I have set my pom file to ask Maven to compile my source code to be version 1.5 compatible using the source
and target
config params. Here is my pom:
<project xmlns="http://maven.apache开发者_如何学JAVA.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>
And I have a simple main class like this:
package com.user;
public class Test
{
public static void main(String[] argv)
{
System.out.println("".isEmpty());
}
}
String#isEmpty()
was introduced since Java 1.6. However, compiling my code with mvn compile
works, while I would have expected it to fail because I have set Maven to compile my code to Java 1.5 and String#isEmpty
was introduced in Java 1.6. Could anyone please suggest what I might have done wrong? What is the correct way to force Maven to use a particular Java version when compiling?
For information, I am using Apache Maven 2.2.1 and javac 1.6.0_19.
Thanks.
From the note at the bottom of the compiler-plugin page:
Merely setting the target option does not guarantee that your code actually runs on a JRE with the specified version. The pitfall is unintended usage of APIs that only exist in later JREs which would make your code fail at runtime with a linkage error. To avoid this issue, you can either configure the compiler's boot classpath to match the target JRE or use the Animal Sniffer Maven Plugin to verify your code doesn't use unintended APIs
This means that although you're generating 1.5-level bytecode, you can still (unintentionally) call a 1.6 API method. To flag these invalide API calls, use the plugin they mention.
You need to compile with a lower version of Java if you want it to not find String.isEmpty()
. The source level controls language-level features you can and can't use, such as @Override
on interfaces requiring compilation with source level 1.6. The target level controls the compatibility of the bytecode that compilation produces. Neither have anything to do with available APIs... that's all based on the classpath you use when building, which in your case includes Java 1.6.
精彩评论