12

我一直试图让它工作一段时间,但还没有运气。

我想JAVA_HOME指向 JDK7 运行,但我想为 JVM 5 编译一个项目。我已经阅读了文档,我在 SO 上找到了类似的帖子,但它们似乎都不适用于我的设置。

我第一次尝试设置只是targetsource但我得到了一个错误:

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

[ClassName]getParentLogger()不是抽象的,也不会覆盖抽象方法CommonDataSource

据我了解,该类已在 JDK 7 中更新,并且刚刚添加了引发错误的额外方法。我需要使用具有旧实现的 JDK 5 的运行时,并且一切都应该可以正常工作。所以我这样做:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <verbose>true</verbose>
        <source>1.5</source>
        <target>1.5</target>
        <compilerArguments>
            <bootclasspath>${env.JAVA5_HOME}/jre/lib/rt.jar</bootclasspath>
        </compilerArguments>
    </configuration>
</plugin>

我在我的系统上正确设置了 JAVA5_HOME,我可以看到它在日志中加载了正确的类,但我遇到了另一个错误:

[loading ZipFileIndexFileObject[c:\Program Files\Java\jdk1.5.0_22\jre\lib\rt.jar(*.class)]]
...
...
[ClassName]错误:包javax.crypto不存在

这很公平,因为我没有jce.jarbootclasspath. 不过,有一件事让我感到困惑。即使bootclasspath只包含 Java 5 运行时,我在类路径中有很多来自 JRE7 的库。它们没有在任何地方指定。

[类文件的搜索路径:c:\Program Files (x86)\Java\jdk1.5.0_22\jre\lib\rt.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\ dnsns.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\localedata.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\sunec.jar, c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\sunjce_provider.jar,c:\Program Files\Java\jdk1.7.0_02\jre\lib\ext\sunmscapi.jar,c:\Program文件\Java\jdk1.7.0_02\jre\lib\ext\zipfs.jar, ...]

如果我尝试添加 jce.jar(来自 JRE5),我会回到第一个错误:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <verbose>true</verbose>
        <source>1.5</source>
        <target>1.5</target>
        <compilerArguments>
            <bootclasspath>${env.JAVA5_HOME}/jre/lib/rt.jar${path.separator}${env.JAVA5_HOME}/jre/lib/jce.jar</bootclasspath>
        </compilerArguments>
    </configuration>
</plugin>

类型 [ClassName] 必须实现继承的抽象方法 CommonDataSource.getParentLogger()

我也看不到被加载的痕迹rt.jar,但我没有收到java.lang未找到的错误,因此类路径上正在加载一些类。

我将通过制作一个JAVA_HOME在构建之前覆盖并在之后将其设置回来的批处理脚本来临时修复它,但我真的希望以正确的方式完成。这似乎不是一个极端的用例。:)

我在这里做错了什么?

4

5 回答 5

6

这个答案是针对问题的标题,而不是针对问题的具体问题进行详细说明。

我最终在我的项目中使用了这个解决方案,它允许我通过激活 maven 配置文件有选择地使用自定义引导类路径。我强烈建议为此使用配置文件,否则它会使任何没有设置环境变量的人构建失败(非常糟糕,尤其是对于开源项目)。我只在我的 IDE 中为“清理和构建”操作激活此配置文件。

    <profile>
        <id>compileWithJava5</id>
        <!--
            NOTE
            Make sure to set the environment variable JAVA5_HOME
            to your JDK 1.5 HOME when using this profile.
        -->
        <properties>
            <java.5.home>${env.JAVA5_HOME}</java.5.home>
            <java.5.libs>${java.5.home}/jre/lib</java.5.libs>
            <java.5.bootclasspath>${java.5.libs}/rt.jar${path.separator}${java.5.libs}/jce.jar</java.5.bootclasspath>
        </properties>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.5</source>
                        <target>1.5</target>
                        <compilerArguments>
                            <bootclasspath>${java.5.bootclasspath}</bootclasspath>
                        </compilerArguments>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
于 2014-03-14T07:45:17.077 回答
3

以前版本的Java 我们不是特别擅长支持Java 以前的版本。对于 Java 7,它似乎要好得多。

这是一个可以在任何版本下编译的程序。

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

$ javac -target 1.7 -source 1.7 Main.java
$ javac -target 1.6 -source 1.6 Main.java
warning: [options] bootstrap class path not set in conjunction with -source 1.6
1 warning
$ javac -Xbootclasspath:/usr/java/jdk1.6.0_29/jre/lib/rt.jar -target 1.6 -source 1.6 Main.java
$ javac -Xbootclasspath:/usr/java/jdk1.5.0_22/jre/lib/rt.jar -target 1.5 -source 1.5 Main.java
$ javac -Xbootclasspath:/usr/java/jdk1.4.0_30/jre/lib/rt.jar -target 1.4 -source 1.4 Main.java
$ javac -Xbootclasspath:/usr/java/jdk1.3.1_29/jre/lib/rt.jar -target 1.3 -source 1.3 Main.java
$ javac -Xbootclasspath:/usr/java/jdk1.2.2_017/jre/lib/rt.jar -target 1.2 -source 1.2 Main.java
$ javac -Xbootclasspath:/usr/java/jdk1.1.8_16/jre/lib/rt.jar -target 1.1 -source 1.2 Main.java
$ javac -Xbootclasspath:/usr/java/jdk1.1.8_16/jre/lib/rt.jar -target 1.1 -source 1.1 Main.java
javac: invalid source release: 1.1
Usage: javac  
use -help for a list of possible options
$ javac -Xbootclasspath:/usr/java/jdk1.1.8_16/jre/lib/rt.jar -target 1.0 -source 1.0 Main.java
javac: invalid target release: 1.0
Usage: javac  
use -help for a list of possible options

如果您需要为以前的 Java 版本进行编译,则需要提供一个引导类路径,最好是为您要编译的 Java 版本提供一个引导类路径。Java 7 似乎能够一直支持到 Java 1.2

于 2012-02-06T19:22:20.117 回答
1

问题在于 Java 7 的向后兼容性。

由于无法解决不同性质的问题,很少有类不保持向后兼容性,DataSource 恰好是其中之一。

因此,要么调整你的类以尊重新的签名(即使在向后兼容模式下),或者你将被迫使用不同版本的虚拟机。

您可以在此处阅读更多信息: http ://www.oracle.com/technetwork/java/javase/compatibility-417013.html

于 2013-02-11T13:29:37.297 回答
1

如果需要,您可以使用 maven-compiler-plugin 上的 bootclasspath 配置选项:

<compilerArguments>
    <bootclasspath>xxxxxxxxx</bootclasspath>
</compilerArguments>

你可以在这里阅读更多关于它的信息。请参阅示例下方的注释。

于 2012-02-06T18:41:47.367 回答
1

要在 Maven 编译器选项中使用多个 jar,请在 jar 之间使用 ${path.separator} 字符串:

<compilerArguments>
   <bootclasspath>${env.JAVA5_HOME}/jre/lib/rt.jar${path.separator}${env.JAVA5_HOME}/jre/lib/jce.jar${path.separator}${env.JAVA5_HOME}/jre/lib/jsse.jar</bootclasspath>
</compilerArguments>
于 2013-10-01T11:11:32.973 回答