Maven – 使用JDK 7编译JVM 5

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

我想运行JAVA_HOME指向JDK7,但我想为JVM 5编译一个项目。我已阅读文档 ,我在SO上发现了类似的post ,但它们似乎都没有在我的设置中工作。

我首先尝试设置targetsource但我得到一个错误:

  org.apache.maven.plugins maven-compiler-plugin  1.5 1.5   

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

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

  org.apache.maven.plugins maven-compiler-plugin  true 1.5 1.5  ${env.JAVA5_HOME}/jre/lib/rt.jar    

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

[loading ZipFileIndexFileObject[c:\Program Files\Java\jdk1.5.0_22\jre\lib\rt.jar(*.class)]]


[ClassName]错误:包javax.crypto不存在

这是公平的,因为我没有在jce.jar包含jce.jar (加密类)。 但是有一件事让我很困惑。 尽管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 Files \ Java \ jdk1.7.0_02 \ jre \ lib \ ext \ zipfs.jar,…]

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

  org.apache.maven.plugins maven-compiler-plugin  true 1.5 1.5  ${env.JAVA5_HOME}/jre/lib/rt.jar${path.separator}${env.JAVA5_HOME}/jre/lib/jce.jar    

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

我也看不到正在加载的rt.jar痕迹,但我没有得到java.lang not found错误,所以在类路径上加载了一些类。

我会通过在构建之前制作一个覆盖JAVA_HOME的批处理脚本来暂时修复它,然后将其设置回来,但我真的希望这样做是正确的。 这似乎不是一个极端的用例。 🙂

我在这做错了什么?

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

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

   compileWithJava5   ${env.JAVA5_HOME} ${java.5.home}/jre/lib ${java.5.libs}/rt.jar${path.separator}${java.5.libs}/jce.jar     org.apache.maven.plugins maven-compiler-plugin  1.5 1.5  ${java.5.bootclasspath}       

以前的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

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

  xxxxxxxxx  

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

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

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

因此,要么让您的类适应新签名(即使在向后兼容模式下),要么您将被迫使用不同版本的虚拟机。

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

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

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