Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting the -source and -target of the Java Compiler with Maven - doesn't work

Tags:

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

like image 768
His Avatar asked Feb 25 '11 02:02

His


2 Answers

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.

like image 114
Mike Reedell Avatar answered Sep 18 '22 04:09

Mike Reedell


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.

like image 36
ColinD Avatar answered Sep 19 '22 04:09

ColinD