Java
来自 维基百科
- Java最初由Sun Microsystems开发,于1995年作为Sun Microsystems Java平台的核心组件发布。该语言从C和C++中汲取了大量语法,但拥有更简单的对象模型和更少底层功能。Java应用程序通常编译为字节码,可以在任何Java虚拟机(JVM)上运行,而与计算机体系结构无关。
Arch Linux官方支持开源的OpenJDK 版本 8、11、17、21和25——长期支持(LTS)版本。所有这些JVM都可以安装而不会发生冲突,并可以使用辅助脚本archlinux-java进行切换(通过java-runtime-common包安装)。 Arch用户仓库中还有其他几个Java环境可用,但不受官方支持。
安装
两个通用包分别作为依赖引入,名为java-runtime-common(包含Java运行时环境的通用文件)和java-environment-common(包含Java开发工具包的通用文件)。
提供的/etc/profile.d/jre.sh和/etc/profile.d/jre.csh文件指向一个链接位置/usr/lib/jvm/default/bin,该位置由archlinux-java辅助脚本设置。
/usr/lib/jvm/default和/usr/lib/jvm/default-runtime符号链接应始终使用archlinux-java进行编辑,该命令用于显示和指向一个工作的默认Java运行时环境。Java安装的大多数可执行文件通过/usr/bin/中的直接链接提供,而其他文件则在$PATH中可用。
OpenJDK
OpenJDK是Java平台,标准版(Java SE)的开源实现,被指定为官方参考实现。OpenJDK构建有多个分发商,例如Adoptium(以前称为AdoptOpenJDK)和Amazon Corretto。Arch Linux的OpenJDK包是从上游OpenJDK源代码构建的。
- 无头JRE
- 最小的Java运行时环境—用于执行非GUI Java程序。
- 完整JRE
- 完整的Java运行时环境—用于执行GUI Java程序。
- JDK
- Java开发工具包—用于Java开发。
JDK、完整JRE和无头JRE相互冲突,因为较小的包是子集。
- JDK冲突并提供完整JRE,
- 完整JRE冲突并提供无头JRE。
IcedTea-Web — Java Web Start 和已弃用的Java浏览器插件。
OpenJDK EA — Oracle的OpenJDK早期访问构建版,用于开发版本。
OpenJDK GA — Oracle的OpenJDK通用发布版构建版。
OpenJDK Wakefield — JDK中用于Wayland显示服务器的支持实现。
OpenJFX
OpenJFX是JavaFX的开源实现。如果您使用的是Oracle JDK,则无需安装此包。此包仅涉及Java(OpenJDK项目)的开源实现及其派生版本的使用者。
| 版本 | 运行时环境和开发工具包 | 文档 | 源 |
|---|---|---|---|
| OpenJFX 26 | java-openjfxAUR | java-openjfx-docAUR | java-openjfx-srcAUR |
| OpenJFX 21 | java21-openjfxAUR | java21-openjfx-docAUR | java21-openjfx-srcAUR |
| OpenJFX 17 | java17-openjfxAUR | java17-openjfx-docAUR | java17-openjfx-srcAUR |
| OpenJFX 11 | java11-openjfxAUR | java11-openjfx-docAUR | java11-openjfx-srcAUR |
| OpenJFX 8 | java8-openjfxAUR | java8-openjfx-docAUR | java8-openjfx-srcAUR |
其他实现
- AWS Corretto — Amazon Web Services 的 OpenJDK 发行版。
- https://aws.amazon.com/corretto/ || amazon-corretto-8AUR amazon-corretto-11AUR amazon-corretto-17AUR amazon-corretto-21-binAUR
- Azul JDK — Azul 的 JDK 实现。请注意,Azul Zulu OpenJDK 版本是开源的,而 Azul Zulu Prime OpenJDK 版本是用于开发和评估的免费商业产品。
- https://www.azul.com/downloads/ ||
- Zulu: zulu-8-binAUR zulu-11-binAUR zulu-17-binAUR zulu-21-binAUR
- Zulu Prime: zing-8-binAUR jdk17-zulu-prime-binAUR zing-21-binAUR
- Eclipse Adoptium/Temurin — Eclipse 的 JRE/JDK 实现,基于 Hotspot JVM(前身为 AdoptOpenJDK)。请注意,JRE 的名称为 Eclipse Temurin。
- https://adoptium.net/ || jdk-temurinAUR jdk17-temurinAUR jdk11-temurinAUR
- IBM Certified — IBM Semeru Runtime Certified Edition。
- IBM J9 — IBM 的 JRE 实现,使用 OpenJ9 贡献。
- https://www.ibm.com/support/pages/java-sdk-downloads || jdk8-j9-binAUR jdk7-j9-binAUR jdk7r1-j9-binAUR
- Liberica JDK — BellSoft 的 Liberica JDK 实现。
- https://bell-sw.com/libericajdk/ || liberica-jre-8-full-binAUR liberica-jdk-8-full-binAUR liberica-jre-11-binAUR liberica-jre-11-full-binAUR liberica-jdk-11-binAUR liberica-jdk-11-full-binAUR liberica-jdk-17-full-binAUR liberica-jdk-21-full-binAUR
- Microsoft OpenJDK — Microsoft 的 OpenJDK 发行版。
- https://www.microsoft.com/openjdk/ || microsoft-openjdk-11-binAUR microsoft-openjdk-17-binAUR microsoft-openjdk-21-binAUR
- OpenJ9 — Eclipse 的 JRE/JDK 实现,基于 IBM 贡献的 J9 JVM。
- https://www.eclipse.org/openj9/ || jdk-openj9-binAUR jdk17-openj9-binAUR jdk11-openj9-binAUR jdk8-openj9-binAUR
- Oracle JDK — Oracle 的商业许可 OpenJDK 构建版。请注意,某些版本只能通过手动下载获得,这需要签署 OTN 协议并创建 Oracle 账户。
- https://www.oracle.com/java/technologies/downloads/ ||
- JRE: jreAUR jre-ltsAUR jre11AUR jre8AUR jre7AUR
- JDK: jdkAUR jdk-ltsAUR jdk11AUR jdk8AUR jdk7AUR
bin32- 来找到,例如 bin32-jreAUR。它们使用 java32-runtime-commonAUR,其功能相当于通过添加后缀 32 来实现 java-runtime-common,例如 java32。同样的类比也适用于 java32-environment-commonAUR,它仅被 32 位 JDK 包使用。开发工具
有关集成开发环境,请参阅 应用程序/实用工具列表#集成开发环境 以及专门的 Java IDE 子章节。
为了阻止逆向工程,可以使用混淆器,例如 proguardAUR。
反编译器
- CFR — Java 反编译器,支持 Java 9、10 及更高版本的现代特性。
- Fernflower — Java 的分析反编译器,作为 IntelliJ IDEA 的一部分开发。
- https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine || fernflower-gitAUR
- Vineflower — 从 Fernflower 分叉的 Java 反编译器,旨在提高代码质量。也可用作 IntelliJ IDEA 插件。
- Krakatau — Java 反编译器、汇编器和反汇编器。
- Procyon decompiler — 实验性 Java 反编译器,灵感来自 ILSpy 和 Mono.Cecil。
- Java Decompiler (JD-Core) — 流行的 Java 反编译器,提供 GUI(参见 JD-GUI)并支持 Java 1-10。
- Jadx — Android DEX 转 Java 反编译器,带有可选 GUI(参见 Jadx-GUI)。
- JAD — 未维护的 Java 反编译器(最后版本 2006)。
GUI前端
- Bytecode Viewer — Java 逆向工程套件,包括反编译器、编辑器和调试器;CFR/Fernflower/Procyon 的前端。
- Recaf — 一个易于使用的现代 Java 字节码编辑器,它抽象了 Java 程序的复杂性;CFR/Fernflower/Procyon 的前端。
- Java Decompiler (JD-GUI) — 流行的 Java 反编译器,提供 GUI 并支持 Java 1-10;JD-Core 的前端。
- Jadx-GUI — Android APK DEX 转 Java 反编译器,带有可选 GUI;Jadx 的前端。
- Luyten — 一个开源的 Java 反编译器 GUI;Procyon 的前端。
切换JVM
辅助脚本archlinux-java(包:java-runtime-common)提供了此类功能。
archlinux-java <COMMAND> COMMAND: status List installed Java environments and enabled one get Return the short name of the Java environment set as default set <JAVA_ENV> Force <JAVA_ENV> as default unset Unset current default Java environment fix Fix an invalid/broken default Java environment configuration
列出已安装的兼容Java环境
$ archlinux-java status
示例
$ archlinux-java status
Available Java environments: java-11-openjdk (default) java-8-openjdk/jre
注意(default)表示java-11-openjdk当前被设置为默认。调用java和其他二进制文件将依赖于此Java安装。另外请注意,上一个输出只显示OpenJDK 8的JRE部分已安装。
更改默认Java环境
# archlinux-java set <JAVA_ENV_NAME>
示例
# archlinux-java set java-8-openjdk/jre
<JAVA_ENV_NAME>名称,请使用archlinux-java status。请注意,archlinux-java不允许您设置无效的Java环境。在上一个示例中,已安装jre8-openjdk但未安装jdk8-openjdk,因此尝试设置java-8-openjdk将失败。
# archlinux-java set java-8-openjdk
'/usr/lib/jvm/java-8-openjdk' is not a valid Java environment path
取消设置默认Java环境
通常无需取消设置Java环境,因为提供它们的包应该会处理这个问题。如果您仍想这样做,只需使用unset命令即可。
# archlinux-java unset
修复默认Java环境
如果设置了无效的Java环境链接,调用archlinux-java fix命令会尝试修复它。另请注意,如果未设置默认Java环境,该命令将查找有效的环境并尝试为您设置。官方支持的包“OpenJDK 8”将按此顺序优先考虑,然后是其他已安装的环境。
# archlinux-java fix
使用非默认Java版本启动应用程序
如果您想使用与默认版本不同的Java版本启动应用程序(例如,如果您在系统上同时安装了版本18—默认版本—和版本11,并且想使用Java 11),您可以将您的应用程序包装在一个小shell脚本中,以本地更改Java的默认路径。
#!/bin/sh export PATH="/usr/lib/jvm/java-11-openjdk/bin/:$PATH" exec /path/to/application "$@"
对于systemd服务,您可以在drop-in文件中将JAVA_HOME附加到环境变量中。
/etc/systemd/system/unit.d/override.conf
[Service] Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk
支持archlinux-java的包前置条件
archlinux32-java,用于32位Java包,其中适当包含32到包/可执行文件名称中(如果适用)。本节面向希望在AUR中提供备用JVM包并能够集成到Arch Linux JVM方案(即与archlinux-java兼容)的打包者;为此,包应
- 将所有文件放置在
/usr/lib/jvm/java-${JAVA_MAJOR_VERSION}-${VENDOR_NAME}下 - 确保java-runtime-common和java-environment-common提供的链接的所有可执行文件都包含在相应的包中。
- 从
/usr/bin提供到可执行文件的链接,仅当这些链接不属于java-runtime-common和java-environment-common时。 - 在man页名称后加上
-${VENDOR_NAME}${JAVA_MAJOR_VERSION}以避免冲突(参见jre8-openjdk文件列表,其中man页以-openjdk8结尾)。 - 不要声明与任何其他JDK、
java-runtime、java-runtime-headless或java-environment的冲突或替换。 - 在install函数中使用脚本
archlinux-java将Java环境设置为默认值,前提是尚无其他有效的Java环境被设置(即:包不应强制设置为默认值)。例如,请参阅官方支持的Java环境包源。
另请注意,
- 需要任何Java环境的包应像往常一样声明对
java-runtime、java-runtime-headless或java-environment的依赖。 - 需要特定Java供应商的包应声明对相应包的依赖。
- OpenJDK包现在声明
provides="java-runtime-openjdk=${pkgver}"等。这使得第三方包可以声明对OpenJDK的依赖而无需指定版本。
技巧与提示
大多数Java应用程序的行为可以通过向Java运行时提供预定义变量来控制。根据此论坛帖子,一种方法是在您的~/.bash_profile中添加以下行(或在/etc/profile.d/jre.sh中添加,以影响不通过 sourcing ~/.bash_profile运行的程序)
export JDK_JAVA_OPTIONS="-D<option 1> -D<option 2>..."
例如,使用系统抗锯齿字体并使swing使用GTK外观
export JDK_JAVA_OPTIONS='-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel'
存在三个这样的变量,下面表格中解释的选项具有更高的优先级。
| JAVA_TOOL_OPTIONS | 影响应用程序以及javac或jshell等工具。 |
| JDK_JAVA_OPTIONS | 影响应用程序(通过java命令启动的所有内容)。需要Java 9。 |
| (命令行选项) | 在“类名”参数之前指定的参数是Java选项。 |
| _JAVA_OPTIONS | 旧方法,影响应用程序和工具。 |
更好的字体渲染
Java的闭源和开源实现都被发现在字体抗锯齿方面实现不当。可以通过以下选项修复:-Dawt.useSystemAAFontSettings=on, -Dswing.aatext=true
有关更详细的信息,请参见Java运行时环境字体。
抑制命令行中的“Picked up JDK_JAVA_OPTIONS”消息
设置JDK_JAVA_OPTIONS环境变量会使java(openjdk)向stderr输出类似“Picked up JDK_JAVA_OPTIONS=...”的消息。要抑制这些消息在终端中的显示,您可以在~/.bashrc中取消设置该环境变量,并将java别名为传递相同的选项作为命令行参数。
SILENT_JAVA_OPTIONS="$JDK_JAVA_OPTIONS" unset JDK_JAVA_OPTIONS alias java='java "$SILENT_JAVA_OPTIONS"'
非交互式shell,如Java程序的启动脚本,(通常)不读取~/.bashrc,但仍然继承其父进程导出的变量(这些变量又在某个时候从读取~/.bash_profile的登录shell继承)。对于它们读取的情况,通常会在~/.bashrc的顶部放置一个语句,以避免读取该文件。这样,变量就会传递给通过桌面菜单启动的程序,而在交互式shell中,消息会干扰别名(这些别名又不能在脚本中使用)。
GTK LookAndFeel
如果您的Java程序外观不佳,您可能需要设置swing组件的默认外观。
swing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel
一些Java程序坚持使用跨平台的Metal外观。在其中一些情况下,您可以通过设置以下属性来强制这些应用程序使用GTK外观。
swing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel
GTK3支持
在 9 版本之前的 Java 版本中,GTK LookAndFeel 链接到 GTK2,而许多较新的桌面应用程序使用 GTK3。GTK 版本之间的不兼容可能会破坏使用带有 GUI 的 Java 插件的应用程序,因为不支持在同一进程中混合使用 GTK2 和 GTK3(例如 LibreOffice 5.0)。
GTK LookAndFeel 可以针对 GTK 版本 2、2.2 和 3 运行,默认使用 GTK3。可以通过设置以下属性来覆盖此设置。
jdk.gtk.version=2.2
HiDPI
根据 GUI 框架的不同,可以使用不同的方法启用 HiDPI#Java 应用程序。
更好的 2D 性能
切换到基于 OpenGL 的硬件加速管道将提高 2D 性能。
export JDK_JAVA_OPTIONS='-Dsun.java2d.opengl=true'
故障排除
MySQL
由于 JDBC 驱动程序通常在 URL 中使用端口来建立与数据库的连接,因此即使它们可能运行在同一主机上,它也被认为是“远程”的(即,默认情况下 MySQL 不会监听该端口)。因此,要使用 JDBC 和 MySQL,您应该启用对 MySQL 的远程访问,遵循 MariaDB#Grant remote access 中的说明。
IntelliJ IDEA
如果 IntelliJ IDEA 在使用系统 Java SDK 路径时输出 The selected directory is not a valid home for JDK,您可能需要安装不同的 JDK 包并将其选为 IDEA 的 JDK。
模拟另一个窗口管理器
您可以使用来自 suckless.org 的 wmname 包,让 JVM 认为您正在运行另一个窗口管理器。这可以解决 Java GUI 在 Awesome、Dwm 或 Ratpoison 等窗口管理器中出现的渲染问题。这是因为 JVM 包含一个硬编码的已知非重叠窗口管理器列表。为了达到最大的讽刺效果,一些用户喜欢模拟 Sun 公司编写的非重叠窗口管理器 LG3D(Java 编写的 Project Looking Glass)。尝试设置 compiz、Metacity 或 LG3D。
$ wmname window_manager_name
在发出 wmname 命令后,您必须重新启动相关应用程序。
或者,可以使用创建以在 MATE 中设置 WM 名称并解决 Java Swing 应用程序全屏启动时工作不正确的 bug 的 javaagent JavaMatePatch。将 -javaagent:JavaMatePatch-1.0.0-SNAPSHOT.jar=window_manager_name 添加到 Java 选项中以使用它。
无法识别的字体
除了下面 #更好的字体渲染 中的建议之外,一些字体仍可能无法被识别。如果是这种情况,很有可能是使用了 Microsoft 字体。安装 ttf-ms-fontsAUR。
某些应用程序缺少文本
如果某些应用程序完全缺少文本,使用 #技巧和窍门 下的选项,如 FS#40871 中建议的那样,可能会有帮助。
灰色窗口,应用程序未随 WM 调整大小,菜单立即关闭
标准的 Java GUI 工具包有一个硬编码的“非重叠”窗口管理器列表。如果使用的是不在该列表中的窗口管理器,运行某些 Java 应用程序可能会出现问题。最常见的问题之一是“灰色块”,此时 Java 应用程序会渲染成一个纯灰色框而不是渲染 GUI。另一个问题可能是菜单响应您的点击,但立即关闭。
有几种方法可能有助于解决此问题。
- 请参阅 #模拟另一个窗口管理器。
- 设置
_JAVA_AWT_WM_NONREPARENTING=1环境变量。 - 对于较新版本,设置
AWT_TOOLKIT=MToolkit环境变量。 - 对于 xmonad,使用 SetWMName。但是,当同时使用
XMonad.Hooks.EwmhDesktops时,其效果可能会被取消。在这种情况下,将LogHook追加>> setWMName "LG3D"可能会有帮助。
有关更多信息,请参阅 Java 应用程序问题,Applet Java 控制台。
调试 JavaFX 应用程序时系统冻结
如果在调试 JavaFX 应用程序时系统冻结,可以尝试提供 JVM 选项 -Dsun.awt.disablegrab=true。
请参阅 https://bugs.java.com/bugdatabase/view_bug?bug_id=6714678
JavaFX 的 MediaPlayer 构造函数抛出异常
从 JavaFX 的声音模块创建 MediaPlayer 类实例可能会抛出以下异常(Oracle JDK 和 OpenJDK 都会出现)
... (i.e. FXMLLoader construction exceptions) ... Caused by: MediaException: UNKNOWN : com.sun.media.jfxmedia.MediaException: Could not create player! : com.sun.media.jfxmedia.MediaException: Could not create player! at javafx.scene.media.MediaException.exceptionToMediaException(MediaException.java:146) at javafx.scene.media.MediaPlayer.init(MediaPlayer.java:511) at javafx.scene.media.MediaPlayer.<init>(MediaPlayer.java:414) at <constructor call> ...
这是 JavaFX 与 Arch Linux 存储库中提供的现代 ffmpeg 构建不兼容的结果。
可行的解决方案是安装 ffmpeg-compat-55AUR。或者,如果前一个版本构建失败,安装 ffmpeg3.4AUR 可能有效。
请参阅 https://www.reddit.com/r/archlinux/comments/70o8o6/using_a_javafx_mediaplayer_in_arch/
Java 应用程序无法打开外部链接
如果 Java 应用程序无法打开到例如您的 Web 浏览器的链接,请安装 gvfs。这是 Desktop.Action.BROWSE 方法所必需的。请参阅 [1] 应用程序打印错误消息 java.lang.UnsupportedOperationException: The BROWSE action is not supported on the current platform! 是此问题的可靠指示。
初始化 QuantumRenderer 时出错:未找到合适的管道
可能的问题/解决方案
- 缺少 GTK2。安装 gtk2AUR
- 缺少 OpenJFX。安装 java-openjfxAUR