首页 文章

Maven:javac:源版本1.6需要目标版本1.6

提问于
浏览
25

注意:这似乎是“javac”程序中的限制 .

我有需要为Java 5 JVM构建的Java 6代码 . 我之前使用javac ant目标(使用JDK编译器和ecj)的工作使我相信它只是设置javac的源和目标 . 因此这个pom.xml片段:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.5</target>
    </configuration>
</plugin>

它可以在Eclipse 3.7中使用Maven支持按预期工作 . 不幸的是,直接从命令行运行Maven给了我

javac: source release 1.6 requires target release 1.6

javac -source 1.6 -target 1.5 生成的相同 . 为了澄清,这是Ubuntu的官方OpenJDK 6

x@JENKINS:~$ javac -version
javac 1.6.0_20
x@JENKINS:~$ javac -source 1.6 -target 1.5
javac: source release 1.6 requires target release 1.6
x@JENKINS:~$

官方Oracle Java 7 JDK for Windows显示了相同的行为 .

注意:我不想构建Java 5库或任何东西 . 只是活动的javac生成Java 5兼容的字节码 .

如何在仍然与Eclipse Maven插件兼容的同时获得我想要的内容?

(编辑:除了@Override我还想在Java 6中使用JAX-WS库进行编译时使用,但仍然生成Java 5字节代码 - 我可以在部署时故意在Web容器中添加JAX-WS库到Java 5安装)


编辑:事实证明maven-compiler-plugin可以被告知使用另一个编译器,Eclipse编译器可以这样做:

<plugin>
            <!-- Using the eclipse compiler allows for different source and target, 
                which is a good thing (outweighing that this is a rarely used combination, 
                and most people use javac) This should also allow us to run maven builds 
                on a JRE and not a JDK. -->

            <!-- Note that initial experiments with an earlier version of maven-compiler-plugin 
                showed that the eclipse compiler bundled with that gave incorrect lines in 
                the debug information. By using a newer version of the plexus-compiler-eclipse 
                plugin this is hopefully less of an issue. If not we must also bundle a newer 
                version of the eclipse compiler itself. -->

            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <source>1.6</source>
                <target>1.5</target>
                <debug>true</debug>
                <optimize>false</optimize>
                <fork>true</fork>
                <compilerId>eclipse</compilerId>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.codehaus.plexus</groupId>
                    <artifactId>plexus-compiler-eclipse</artifactId>
                    <version>2.1</version>
                </dependency>
            </dependencies>
        </plugin>

它将类编译为Java 1.5字节码而没有抱怨 . 对于Eclipse Java EE 4.2.2的m2e,它也支持“开箱即用” .

编辑:我发现javadoc工具不喜欢Eclipse编译器的输出 .

编辑2015-06-28:我最近做了一个快速测试,最新的ecj(对应于Eclipse 4.4)与javadoc一起工作正常 .

6 回答

  • 1

    我相信你需要设置 -bootclasspath 以便 javac 编译JDK 1.5 bootstrap类 .

    尝试:

    javac -source 1.6 -target 1.5 -bootclasspath /path/to/jdk1.5/lib/rt.jar -extdirs "" Foo.java
    

    UPDATE:

    尝试删除 -source 选项,但保留 -target 选项 .

    我刚试了一下:

    # no source, only target => COMPILES to 1.5
    $ javac -target 1.5 Foo.java
    $ javap -v  Foo | grep version
      minor version: 0
      major version: 49
    
    # no source, no target => COMPILES to 1.6
    $ javac Foo.java
    $ javap -v  Foo | grep version
      minor version: 0
      major version: 50
    
    # both source and target => ERROR
    $ javac -source 1.6 -target 1.5 Foo.java
    javac: source release 1.6 requires target release 1.6
    
    $ javac -version
    javac 1.6.0_21
    
  • 8

    限制在javac . 解决方案是告诉maven使用另一个编译器 . 请参阅问题了解详情 .

  • -1

    看来如果你想做交叉编译,你需要提供一些额外的参数 -bootclasspath-extdirs ,虽然我相信你只需要第一个 . 对于使用Javac和示例,可以在here找到附加选项here(交叉编译选项部分)的说明 .

    然后,您需要为maven-compiler-plugin配置这些选项 . 根据我的理解,你需要设置插件到fork,以便它将使用编译器参数而不是内置编译器 . 你可以找到所有选项的列表here

    <build>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.6</source>
                        <target>1.5</target>
                        <fork>true</fork>
                        <compilerArguments>
                            <bootclasspath>${1.5.0jdk}\lib\rt.jar</bootclasspath>
                       </compilerArguments>
                   </configuration>
               </plugin>
            ....
           </plugins>
       </build>
    
  • 12

    您使用的Java 6语言功能在Java 5中不存在?据我所知,只有"feature"被添加到该语言中是在 interface 中使用 @Override 注释 . 否则,Java 6和Java 5是源兼容的 . 使用时会发生什么:

    <source>1.5</source>
    <target>1.5</target>
    

    在您的Maven构建文件中?

  • 1

    当我升级IntelliJ IDE时遇到了同样的错误,修复了1.5和1.6的替换,如下所示 .

    <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
    
  • 2

    因此,真正的问题是在需要在Java 1.5类文件中编译的源文件中使用 @Override .

    javac -source 1.5 -target 1.5 aFileWithOverride.java
    

    会这样做的 . 在jdk 7中,这将导致警告

    [options] bootstrap class path not set in conjunction with -source 1.5
    

    这在jdk 6中是不存在的 .

    要消除此警告,可以通过将java 6(或更高版本) java.lang.annotation 软件包添加到java 5 rt.jar 来创建特殊的引导类jar .

相关问题