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

发布于 2024-12-28 16:49:52 字数 3217 浏览 0 评论 0原文

注意:这似乎是“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>

在具有 Maven 支持的 Eclipse 3.7 中按预期工作。不幸的是,直接从命令行运行 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:~$

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

注意:我不想针对 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配合良好。

NOTE: This appears to be a limit in the "javac" program.

I have Java 6 code that needs to be built for a Java 5 JVM. My previous work with the javac ant target (both with the JDK compiler and with ecj) led me to believe that it would simply be a matter of setting source and target for javac. Hence this pom.xml fragment:

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

which works as expected from within Eclipse 3.7 with Maven support. Unfortunately, running Maven directly from the command line give me

javac: source release 1.6 requires target release 1.6

which is the same as generated by javac -source 1.6 -target 1.5. To clarify, this is the official OpenJDK 6 for Ubuntu

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:~$

The official Oracle Java 7 JDK for Windows show the same behavior.

Note: I do not want to build against Java 5 libraries or anything. Just that the active javac generates Java 5 compatible bytecode.

How do I get what I want while still being compatible with the Eclipse Maven plugin?

(EDIT: In addition to the @Override I also want to compile against the JAX-WS libraries in Java 6 when used, but still generated Java 5 byte code - I can then add the JAX-WS libraries deliberately in the web container when deploying to a Java 5 installation)


EDIT: It turns out that maven-compiler-plugin can be told to use another compiler, and the Eclipse compiler can do this:

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

which compiles the class to Java 1.5 bytecode without complaints. This is also supported "out of the box" for m2e for Eclipse Java EE 4.2.2.

EDIT: I found that of all things the javadoc tool dislikes the output from the Eclipse compiler.

EDIT 2015-06-28: I did a quick test recently and the latest ecj (corresponding to Eclipse 4.4) worked fine with javadoc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

对岸观火 2025-01-04 16:49:52

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

The limitation is in javac. The solution is to tell maven to use another compiler. See question for details.

终陌 2025-01-04 16:49:52

看来如果你想进行交叉编译,你需要提供几个额外的参数 -bootclasspath-extdirs,尽管我相信你只需要第一个。有关使用 Javac 的信息和示例,请参见此处 以及附加选项的说明 此处(交叉编译选项部分)。

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

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

It seems if you want to do cross compilation you need to supply a couple of extra arguments -bootclasspath and -extdirs, although I believe you only need the first. For using Javac and example can be found here with an explanation of the additional options here (Cross-Compilation Options section).

You would then need to configure these options for your maven-compiler-plugin. From what I understand you need to set to plugin to fork so that it will use the compiler arguments rather than the built in compiler. You can find a listing of all the options 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>
情仇皆在手 2025-01-04 16:49:52

我相信您还需要设置 -bootclasspath ,以便 javac 针对 JDK 1.5 引导类进行编译。

尝试:

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

更新:

尝试删除-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

I believe you need to set -bootclasspath as well so that javac compiles against JDK 1.5 bootstrap classes.

Try:

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

UPDATE:

Try removing the -source option, but keep the -target option.

I just tested it out:

# 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
酒浓于脸红 2025-01-04 16:49:52

您使用的哪些 Java 6 语言功能是 Java 5 中没有的?据我所知,该语言中添加的唯一“功能”是在接口中使用@Override注释。否则,Java 6 和 Java 5 是源兼容的。 使用:时会发生什么?

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

当您在 Maven 构建文件中

What Java 6 language features are you using that are not present in Java 5? As far as I can tell, the only "feature" that's been added to the language is the use of the @Override annotation in interfaces. Otherwise, Java 6 and Java 5 are source-compatible. What happens when you use:

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

in your Maven build file?

此生挚爱伱 2025-01-04 16:49:52

当我升级 IntelliJ IDE 时,我遇到了同样的错误,通过将 1.5 替换为 1.6 来修复,如下所示。

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

I had the same error when I upgraded my IntelliJ IDE, it was fixed with the replacement of 1.5 with 1.6 as below.

       <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
泪之魂 2025-01-04 16:49:52

因此,真正的问题是在需要在 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

The real question is thus to use @Override in source files that need to be compiled in Java 1.5 class files.

javac -source 1.5 -target 1.5 aFileWithOverride.java

will do just that. In jdk 7, this will lead to a warning

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

which is absent in jdk 6.

To get rid of this warning a special boot class jar can be created by adding the java 6 (or higher) java.lang.annotation package to a java 5 rt.jar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文