- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
public enum DirectoryWatchService {
INSTANCE;
private java.util.Optional<String> test;
private java.nio.file.Files files;
}
最佳答案
您遇到了source
/target
选项的交叉编译误解。在类路径中使用主版本(JDK 7或8),但希望针对次版本(在您的情况下为6)进行编译。
编译会很好,但是您会在运行时(即 NoClassDefFoundError
或 NoSuchMethodError
,也可能是更通用的 LinkageError
)出现错误。
使用 source
/ target
,Java编译器可以用作交叉编译器,以生成可在实现Java SE规范的早期版本的JDK上运行的类文件。
普遍的信念是,使用两个编译器选项就足够了。但是,source
选项指定要针对哪个版本进行编译,而target
选项指定要支持的最低Java版本。
该编译器可用于字节码生成,并且source
和target
用于在交叉编译期间生成兼容的字节码。但是,编译器不处理Java API(它们作为JDK安装(著名的rt.jar
文件)的一部分提供)。编译器没有任何API知识,只是根据当前的rt.jar
进行编译。因此,当使用JDK 1.7使用target=1.6
进行编译时,编译器仍将指向JDK 7 rt.jar
。
那么,我们实际上如何才能进行正确的交叉编译?
如果source
/target
不与bootclasspath
选项结合使用,则为Since JDK 7, javac prints a warning。在这些情况下,bootclasspath
选项是关键选项,它指向所需目标Java版本的rt.jar
(因此,您需要在计算机中安装目标JDK)。这样,javac
将有效地针对良好的Java API进行编译。
但这可能还不够!
并非所有Java API都来自rt.jar
。 lib\ext
文件夹提供了其他类。为此,使用了另一个javac
选项extdirs
。摘自Oracle官方文档
If you are cross-compiling (compiling classes against bootstrap and extension classes of a different Java platform implementation), this option specifies the directories that contain the extension classes.
source
/
target
和
bootclasspath
选项,我们也可能在交叉编译期间错过某些内容,正如javac文档随附的
official example中所解释的那样。
The Java Platform JDK's javac would also by default compile against its own bootstrap classes, so we need to tell javac to compile against JDK 1.5 bootstrap classes instead. We do this with -bootclasspath and -extdirs. Failing to do this might allow compilation against a Java Platform API that would not be present on a 1.5 VM and would fail at runtime.
Even when the bootclasspath and -source/-target are all set appropriately for cross-compilation, compiler-internal contracts, such as how anonymous inner classes are compiled, may differ between, say, javac in JDK 1.4.2 and javac in JDK 6 running with the -target 1.4 option.
The most reliably way to produce class files that will work on a particular JDK and later is to compile the source files using the oldest JDK of interest. Barring that, the bootclasspath must be set for robust cross-compilation to an older JDK.
source
/
target
和
bootclasspath
的灵活性。 Spring 4始终使用
source
/
target
编译为Java 6,以便字节码仍可以在JRE 6下运行。因此,不使用Java 7/8语言功能:语法保持Java 6级别。
bootclasspath
选项。可选,使用Stream和许多其他Java 8 API。然后,仅在运行时检测到JRE 7/8时,才根据Java 7或Java 8 API注入(inject)bean:聪明的方法!
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.14</version>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java16</artifactId>
<version>1.0</version>
</signature>
</configuration>
<executions>
<execution>
<id>ensure-java-1.6-class-library</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
source
/ target
page of the maven-compiler-plugin
中也建议使用此用法
Note: Merely setting the
target
option does not guarantee that your code actually runs on a JRE with the specified version. The pitfall is unintended usage of APIs that only exist in later JREs which would make your code fail at runtime with a linkage error. To avoid this issue, you can either configure the compiler's boot classpath to match the target JRE or use the Animal Sniffer Maven Plugin to verify your code doesn't use unintended APIs.
javac --release N ...
javac -source N -target N -bootclasspath rtN.jar ...
Information about APIs of earlier releases available to
javac
- Stored in a compressed fashion
- Only provide Java SE N and JDK N-exported APIs that are platform neutral
- Same set of release values N as for
-source
/-target
- Incompatible combinations of options rejected
--release N
方法的主要优点:
- No user need to manage artifacts storing old API information
- Should remove need to use tools like the Maven plugin Animal Sniffer
May use newer compilation idioms than the
javac
in older releases
- Bug fixes
- Speed improvements
3.6.0
版本开始,
maven-compiler-plugin
通过其
release
选项提供了对Java 9的支持:
The
-release
argument for the Java compiler, supported since Java9
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<release>8</release>
</configuration>
</plugin>
关于java - Eclipse/Idea忽略了Maven Java版本配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35913775/
我正在尝试设置我的 git 配置,以便我可以使用工作环境和个人环境。 这是我的 ~.gitconfig 文件的内容(碰巧 work 和 private 在 github 上): [url "git@
我有以下情况。我在 Sheet1 上有一个项目列表,我想将项目复制到 Sheet2 并排除特定项目。 假设我在 Sheet1 上有以下项目列表: 我想将“梨”单元格留在 Sheet2 上。 它应该完全
我试图让 gcc 以不同的语言提供错误消息。但它仍然给我英文的错误信息。 我的语言环境输出 varun@varun-desktop:$ 语言环境 LANG=en_IN LC_CTYPE="es_EC.
我在 Linux x86 上使用 gcc。 我的程序将指向 C 函数的指针导出到 LLVM JIT 函数。调用约定是 cdecl。它在 Windows 上的 MingW 上运行良好。但是奇怪的事情发生
windows 上 php 的奇怪问题...我的应用程序加载了一个“核心”文件,该文件加载了一个设置文件、注册自动加载、进行初始化等。在核心文件的顶部我有 include_once("config.p
在工具|选项|调试器选项 |语言异常可以忽略特定的异常类型。是否可以为每个项目定义这个?例如在调试构建配置中(Delphi 2009 和/或 2010)? /编辑:Reported in QC 最佳答
我在一个文本框旁边有 2 个按钮,在这 2 个按钮后面还有另一个文本框。第一个文本框的 tabindex 为 1000,第一个按钮为 1001,第二个按钮为 1002。第二个文本框的 tabindex
我是 python 新手,正在尝试类型提示,但它们似乎只在某些情况下起作用。它们似乎在属性返回类型上按预期工作,但是当我尝试将整数分配给字符串值(即 self._my_string = 4)时,我没有
问题陈述 我有一些国家和这些国家的州的依赖组合框。我使用 VBA 在第一个组合框中填充唯一值,然后在第二个组合框中动态填充唯一值。该代码似乎忽略了初始传递中的条件。 例如,该代码适用于第一个国家/地区
我对 Javascript 有点陌生。我试图做到这一点,以便单击一个页面上的图像会将您带到一个新页面,并在该新页面上显示特定的 div,因此我使用 sessionStorage 来记住并使用 bool
我不确定我是否正确地处理了这个问题。 我有一个 ASP.NET MVC Web 应用程序。有 4 个主要“页面”通过单击菜单选项,可以选择一个页面,并将该页面选项存储在本地存储中。 现在,如果我刷新页
我的页面工作正常,并按预期显示日期和时间,直到我不得不添加 new Date() 以避免 momentjs deprecation warning 。现在我的约会比应有的时间晚了 5 个小时。 我该如
我需要合并一个 fork 项目。不幸的是,CVS $Id 行不同,因此我尝试的合并工具报告所有文件都不同(其中 95% 只有这一行不同) 是否有一个合并工具可以配置为忽略基于模式的行比较结果? [编辑
我是 python 新手,正在尝试类型提示,但它们似乎只在某些情况下起作用。它们似乎在属性返回类型上按预期工作,但是当我尝试将整数分配给字符串值(即 self._my_string = 4)时,我没有
我正在尝试根据 How do a send an HTTPS request through a proxy in Java? 使用代理访问 https 网页 但是我遇到了一个奇怪的问题:HttpsU
我有一个简单的 CMakeLists.txt 文件: cmake_minimum_required(VERSION 2.8.9) project (sample) add_library(Shared
这个问题在这里已经有了答案: typedef pointer const weirdness (6 个答案) 关闭 8 年前。 我有一个结构体 type_s。然后我将指向 struct type_s
我正在尝试制作一个使用 AES 256 加密的应用程序。不幸的是我无法让它工作。也许我没有完全理解密码逻辑。 所以它正在工作,但据我了解,哈希包含密码。但如果我更改密码,输出是相同的。因此,Crypt
我的文件包含一些行,例如 "This is a string." = "This is a string's content." " Another \" example \"" = " New ex
我尝试使用此查询来获取所选健身房的所有用户。 我的问题是查询忽略了这部分:ual.user_id = weekUsers.user_id 查询似乎获取了与我选择的日期匹配的所有用户 ID,而不检查该用
我是一名优秀的程序员,十分优秀!