我已经看到了Which JDK's distributions can run `javac -source 1.6 -target 1.5`?中讨论的编译选项。我理解源和目标的各个选项。我不明白为什么源版本高于目标版本。编译旧目标的代码是有道理的。但在这种情况下,为什么我们不使用我们希望能够在其上运行的最老目标的源?
答案 0 :(得分:21)
Java向后兼容。您可以使用 -source 选项指定用于编译的java版本,并使用 -target 选项指定要支持的最低java版本。例如。如果我指定1.4的目标,那么我的程序将无法在java 1.3或更低版本上运行。有关详细信息,请参阅以下javac documentation。特别是关于交叉编译选项
的部分答案 1 :(得分:21)
请务必设置bootclasspath以确保您的程序可以在较旧的VM上运行。
来自javac
documentation:
交叉编译示例
以下示例使用javac编译将在1.6 VM上运行的代码。
C\:>javac -source 1.6 -target 1.6 -bootclasspath C:\jdk1.6.0\lib\rt.jar -extdirs "" OldCode.java
-source 1.6
选项指定使用Java编程语言的1.6(或6)版来编译OldCode.java
。选项-target 1.6
选项可确保生成的类文件与1.6 VM兼容。请注意,在大多数情况下,-target
选项的值是-source
选项的值;在此示例中,您可以省略-target
选项。您必须指定
-bootclasspath
选项以指定正确版本的引导类(rt.jar
库)。如果没有,编译器将生成以下警告:C:\>javac -source 1.6 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.6
如果没有指定正确版本的bootstrap类,编译器将使用旧的语言规则(在本例中,它将使用Java编程语言的1.6版本)与新的bootstrap类结合使用,这可能导致在旧平台上不起作用的类文件(在本例中为Java SE 6),因为可以包含对不存在的方法的引用。
答案 2 :(得分:2)
Peter Tseng确实提到了编译过程中要记住的许多要点。事实上,即使我在某个时候遇到过类似的问题,也想分享许多问题的根本原因。
我有一个必须编译的源代码。使它兼容(-source& -target) Java' 1.8' 。代码本身有
java.sql.*
package 经过一些更改后,我最终得到了一个代码,该代码具有相同数量的JUnit测试用例。最终我遇到了java.lang.VerifyError
。当我在不同的库/环境中编译并运行代码时,我发现这样的错误发生时,我感到很震惊。(其中并非如此)。
我几乎想念的是,为了表彰测试必须在一个孤立的环境中运行的事实,Junit&它的测试用例在一个单独的分叉VM中执行
<target name="runJunit">
<junit printonsummary="on"
haltonfailure="off"
fork="true"
forkmode="once">
<formatter />
<batchtest />
<classpath />
</junit>
</target>
这显然将作为一个单独的进程跨越,并作为执行中的独立应用程序。即使IDE同步跨越两个进程,JVM也几乎是孤立的。
在Java 1.7之后,Oracle引入了更严格的验证并稍微更改了类格式 - 包含堆栈映射,用于验证代码是否正确。我见过的例外是因为某些方法没有有效的堆栈映射。我最终尝试包含许多JVM选项来调整设置,但是徒劳无功。
<jvmarg value="bootclasspath:{env.JAVA_HOME}\jre\bin\rt.jar" prefix="-X"/>
没什么用的。唯一的解决方法是包括
<jvmarg value=":UseSplitVerifier" prefix="-XX"/>
在Java 1.7中只允许标称字节码验证。由于这是在Java 1.8中取消的,唯一的选择是使用
<jvmarg value="-noverify"/>
答案 3 :(得分:0)
JDK1.8将不再支持-source和-target小于1.6
"c:\Program Files\Java\jdk1.8.0_121\bin\javac.exe" -source 1.3 HelloWorld.java
warning: [options] bootstrap class path not set in conjunction with -source 1.3
warning: [options] source value 1.3 is obsolete and will be removed in a future release
warning: [options] target value 1.4 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings