Java
来自 Wikipedia 文章
- Java 是一种编程语言,最初由 Sun Microsystems 开发,并于 1995 年作为 Sun Microsystems Java 平台的核心组件发布。该语言的语法很大程度上源自 C 和 C++,但具有更简单的对象模型和更少的底层工具。Java 应用程序通常编译为可以在任何 Java 虚拟机(JVM)上运行的字节码,而与计算机体系结构无关。
Arch Linux 官方支持开源 OpenJDK 版本 8、11、17 和 21 — 长期支持 (LTS) 版本,以及 23 — 最新发布的版本。所有这些 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 源代码 构建的。
- Headless JRE
- 最小 Java 运行时环境——执行非 GUI Java 程序所必需。
- Full JRE
- 完整 Java 运行时环境——执行 GUI Java 程序所必需。
- JDK
- Java 开发工具包——Java 开发所必需。
JDK、full JRE 和 headless JRE 彼此冲突,因为较小的软件包是子集
- JDK 冲突并提供 full JRE,
- full JRE 冲突并提供 headless 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 22 | 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 — 亚马逊网络服务的 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 Builds of OpenJDK 是开源的,而 Azul Zulu Prime Builds of OpenJDK 是商业产品,可免费用于开发和评估。
- https://www.azul.com/downloads/ ||
- Zulu: zulu-8-binAUR zulu-11-binAUR zulu-17-binAUR zulu-21-binAUR
- Zulu Prime: jdk17-zulu-prime-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,其功能类似于 java-runtime-common,通过添加后缀 32
,例如 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 年)。
图形界面前端
- 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 环境,这将查找有效的 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 服务,您可以将 JAVA_HOME
附加到 drop-in 文件 中的环境变量中
/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
的任何 冲突 或 替换 - 在安装函数中使用脚本
archlinux-java
将 Java 环境设置为默认值如果尚未设置其他有效的 Java 环境(即:软件包不应强制安装为默认值)。有关示例,请参阅 官方支持的 Java 环境软件包来源
另请注意
- 需要任何 Java 环境的软件包应像往常一样声明对
java-runtime
、java-runtime-headless
或java-environment
的依赖 - 需要特定 Java 供应商的软件包应声明对相应软件包的依赖
- OpenJDK 软件包现在声明
provides="java-runtime-openjdk=${pkgver}"
等。这使得第三方软件包能够声明对 OpenJDK 的依赖,而无需指定版本。
故障排除
MySQL
由于 JDBC 驱动程序通常在 URL 中使用端口来建立与数据库的连接,即使它们可能运行在同一主机上,它也被认为是“远程”连接(即,MySQL 不会像其默认设置那样监听端口)。因此,要使用 JDBC 和 MySQL,您应该启用对 MySQL 的远程访问,按照 MariaDB#授予远程访问权限 中的说明进行操作。
IntelliJ IDEA
如果 IntelliJ IDEA 输出 The selected directory is not a valid home for JDK
以及系统 Java SDK 路径,您可能需要安装不同的 JDK 软件包并将其选择为 IDEA 的 JDK。
模拟其他窗口管理器
您可以使用来自 suckless.org 的 wmname 来使 JVM 相信您正在运行不同的窗口管理器。这可以解决 Java GUI 在 Awesome 或 Dwm 或 Ratpoison 等窗口管理器中出现的渲染问题。这是可行的,因为 JVM 包含一个硬编码的已知非重父窗口管理器列表。具有讽刺意味的是,一些用户更喜欢模拟 LG3D
,即由 Sun 使用 Java 编写的 非重父窗口管理器。尝试设置 compiz
、Metacity
或 LG3D
。
$ wmname window_manager_name
在发出 wmname 命令后,您必须重启相关的应用程序。
或者,可以使用 javaagent JavaMatePatch,它被创建用于在 MATE 中设置 WM 名称并解决在全屏启动时 java swing 应用程序工作不正常的错误。添加 -javaagent:JavaMatePatch-1.0.0-SNAPSHOT.jar=window_manager_name
到 java 选项中使用它。
字体难以辨认
除了下面在 #更好的字体渲染 中提到的建议之外,某些字体可能仍然难以辨认。如果是这种情况,很有可能是正在使用 Microsoft 字体。安装 ttf-ms-fontsAUR。
某些应用程序中缺少文本
如果某些应用程序完全缺少文本,则使用 #技巧和提示 下的选项可能会有所帮助,如 FS#40871 中建议的那样。
标准的 Java GUI 工具包有一个硬编码的“非重父”窗口管理器列表。如果使用未在该列表中的窗口管理器,则运行某些 Java 应用程序可能会出现问题。最常见的问题之一是“灰色斑点”,即 Java 应用程序渲染为纯灰色框而不是渲染 GUI。另一个可能是菜单响应您的点击,但立即关闭。
以下几种方法可能有所帮助:
- 参见 #模拟其他窗口管理器。
- 设置
_JAVA_AWT_WM_NONREPARENTING=1
环境变量。 - 对于更高版本,设置
AWT_TOOLKIT=MToolkit
环境变量。 - 对于 xmonad,使用 SetWMName。但是,当同时使用
XMonad.Hooks.EwmhDesktops
时,其效果可能会被取消。在这种情况下,将>> setWMName "LG3D"
附加到LogHook
可能会有所帮助。
有关更多信息,请参见 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 缺失。安装 gtk2
- OpenJFX 缺失。安装 java-openjfxAUR
技巧和提示
大多数 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
,但仍然从其父进程继承导出的变量(而父进程又在某个时候从登录 shell 继承了这些变量,登录 shell 读取了 ~/.bash_profile
)。至于它们读取 ~/.bashrc
的情况,通常会在 ~/.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 支持
在 Java 9 之前的版本中,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'