Maven - 使用JDK 7编译JVM 5

时间:2012-02-06 17:47:56

标签: java maven jdk1.5

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

我希望运行JAVA_HOME指向JDK7,但我想为JVM 5编译项目。我已经通读了documentation,我发现了{{3}在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.jar中没有包含bootclasspath(加密类)。但是有一件事让我感到困惑。尽管bootclasspath只包含Java 5运行时,但我在类路径中有很多来自JRE7的库。它们没有在任何地方指定。

  

[类文件的搜索路径:c:\ Program Files   (86)\的Java \ jdk1.5.0_22 \ JRE \ LIB \ rt.jar中,C:\ PROGRAM   文件\的Java \ jdk1.7.0_02 \ JRE \ lib中\分机\ dnsns.jar,C:\ PROGRAM   文件\的Java \ jdk1.7.0_02 \ JRE \ lib中\分机\ localedata.jar,C:\ PROGRAM   文件\的Java \ jdk1.7.0_02 \ JRE \ lib中\分机\ sunec.jar,C:\ PROGRAM   文件\的Java \ jdk1.7.0_02 \ JRE \ lib中\分机\程序(sunjce_provider.jar),C:\ PROGRAM   文件\的Java \ jdk1.7.0_02 \ JRE \ lib中\分机\ sunmscapi.jar,C:\ PROGRAM   Files \ 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的批处理脚本来暂时修复它,然后将其设置回来,但我真的希望这样做是正确的。这似乎不是一个极端的用例。 :)

我在这里做错了什么?

5 个答案:

答案 0 :(得分:5)

这个答案针对问题的标题,而不是针对问题的具体问题。

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

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

答案 1 :(得分: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,则需要提供一个bootclasspath,理想情况下是要编译的Java版本。 Java 7似乎能够支持一直回到Java 1.2

答案 2 :(得分:1)

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

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

您可以阅读更多相关信息here。请参阅示例下的注释。

答案 3 :(得分:1)

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

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

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

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

答案 4 :(得分:1)

要在Maven编译器选项中使用多个Jars,请使用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>