Java

来自 ArchWiki
(重定向自 OpenJDK

来自 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 环境,但未获得官方支持。

安装

注意
  • Arch Linux 仅官方支持 OpenJDK 实现。
  • 安装后,Java 环境需要被 shell$PATH 变量)识别。这可以通过从命令行 sourcing /etc/profile、注销/重新登录 桌面环境 或重新启动来完成。

两个通用软件包分别作为依赖项拉取,名为 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

OpenJDKJava 平台标准版 (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。
版本 Headless JRE Full JRE JDK 文档 来源
OpenJDK 23 jre-openjdk-headless jre-openjdk jdk-openjdk openjdk-doc openjdk-src
OpenJDK 21 jre21-openjdk-headless jre21-openjdk jdk21-openjdk openjdk21-doc openjdk21-src
OpenJDK 17 jre17-openjdk-headless jre17-openjdk jdk17-openjdk openjdk17-doc openjdk17-src
OpenJDK 11 jre11-openjdk-headless jre11-openjdk jdk11-openjdk openjdk11-doc openjdk11-src
OpenJDK 8 jre8-openjdk-headless jre8-openjdk jdk8-openjdk openjdk8-doc openjdk8-src

IcedTea-Web — Java Web Start 和已弃用的 Java 浏览器插件。

https://icedtea.classpath.org/download/icedtea-web-docs/1.8/html/en/icedtea-web.html || icedtea-web

OpenJDK EA — 来自 Oracle 的开发版本的 OpenJDK 早期访问构建。

https://jdk.java.net || java-openjdk-ea-binAUR

OpenJDK GA — 来自 Oracle 的 OpenJDK 一般可用性发布构建。

https://jdk.java.net || java-openjdk-binAUR

OpenJDK Wakefield — 在 JDK 中为 Wayland 显示服务器提供支持实现。

https://openjdk.org/projects/wakefield/ || jdk-openjdk-wakefieldAUR


OpenJFX

OpenJFXJavaFX 的开源实现。如果您使用的是 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。
https://www.ibm.com/semeru-runtimes/downloads || jdk11-j9-binAUR
  • 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


提示: 32 位版本的 Oracle JDK 可以通过添加前缀 bin32- 找到,例如 bin32-jreAUR。它们使用 java32-runtime-commonAUR,其功能类似于 java-runtime-common,通过添加后缀 32,例如 java32。同样的类比适用于 java32-environment-commonAUR,它仅供 32 位 JDK 软件包使用。

开发工具

有关集成开发环境,请参阅 应用程序列表/实用工具#集成开发环境 以及专门的 Java IDE 子章节。

为了阻止逆向工程,可以使用像 proguardAUR 这样的混淆器。

反编译器

  • CFR — Java 反编译器,支持 Java 9、10 及更高版本的现代功能。
https://www.benf.org/other/cfr/ || cfr
  • Fernflower — 用于 Java 的分析反编译器,作为 IntelliJ IDEA 的一部分开发。
https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine || fernflower-gitAUR
  • Vineflower — 从 Fernflower 分支出来的 Java 反编译器,旨在提高代码质量。也可用作 IntelliJ IDEA 插件。
https://github.com/Vineflower/vineflower || vineflowerAUR
  • Krakatau — Java 反编译器、汇编器和反汇编器。
https://github.com/Storyyeller/Krakatau || krakatau-gitAUR
  • Procyon decompiler — 实验性 Java 反编译器,灵感来自 ILSpy 和 Mono.Cecil。
https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler || procyon-decompiler
  • Java Decompiler (JD-Core) — 流行的 Java 反编译器,提供 GUI(参见 JD-GUI)并支持 Java 1-10。
https://java-decompiler.github.io/ || jd-core-javaAUR
  • Jadx — Android DEX 到 Java 反编译器,带有可选的 GUI(参见 Jadx-GUI)。
https://github.com/skylot/jadx || jadx
  • JAD — 未维护的 Java 反编译器(上次发布于 2006 年)。
https://varaneckas.com/jad || jad

图形界面前端

  • Bytecode Viewer — Java 逆向工程套件,包括反编译器、编辑器和调试器;CFR/Fernflower/Procyon 的前端。
https://bytecodeviewer.com || bytecode-viewerAUR
  • Recaf — 易于使用的现代 Java 字节码编辑器,抽象了 Java 程序的复杂性;CFR/Fernflower/Procyon 的前端。
https://www.coley.software/Recaf/ || recaf-binAUR
  • Java Decompiler (JD-GUI) — 流行的 Java 反编译器,提供 GUI 并支持 Java 1-10;JD-Core 的前端。
https://java-decompiler.github.io/ || jd-guiAUR
  • Jadx-GUI — Android APK DEX 到 Java 反编译器,带有可选的 GUI;Jadx 的前端。
https://github.com/skylot/jadx || jadx
  • Luyten — 开源 Java 反编译器 Gui;Procyon 的前端。
https://github.com/deathmarine/Luyten || luytenAUR

在 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-commonjava-environment-common 提供链接的所有可执行文件在相应的软件包中可用
  • 仅当从 /usr/bin 到可执行文件的链接尚不属于 java-runtime-commonjava-environment-common 时,才发送这些链接
  • 后缀 man 手册页为 -${VENDOR_NAME}${JAVA_MAJOR_VERSION} 以防止冲突(请参阅 jre8-openjdk 文件列表,其中 man 手册页后缀为 -openjdk8
  • 不要声明与其他 JDK、java-runtimejava-runtime-headlessjava-environment 的任何 冲突替换
  • 安装函数中使用脚本 archlinux-java 将 Java 环境设置为默认值如果尚未设置其他有效的 Java 环境(即:软件包不应强制安装为默认值)。有关示例,请参阅 官方支持的 Java 环境软件包来源

另请注意

  • 需要任何 Java 环境的软件包应像往常一样声明对 java-runtimejava-runtime-headlessjava-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.orgwmname 来使 JVM 相信您正在运行不同的窗口管理器。这可以解决 Java GUI 在 AwesomeDwmRatpoison 等窗口管理器中出现的渲染问题。这是可行的,因为 JVM 包含一个硬编码的已知非重父窗口管理器列表。具有讽刺意味的是,一些用户更喜欢模拟 LG3D,即由 Sun 使用 Java 编写的 非重父窗口管理器。尝试设置 compizMetacityLG3D

$ 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 中建议的那样。

灰色窗口、应用程序无法随 WM 调整大小、菜单立即关闭

标准的 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 时出错:未找到合适的管道

可能的问题/解决方案

技巧和提示

注意: 本节中的建议适用于所有使用显式安装的(外部)Java 运行时环境的应用程序。某些应用程序与自己的(私有)运行时环境捆绑在一起,或使用自己的 GUI、字体渲染等机制,因此以下内容不能保证有效。

大多数 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 版本 22.23 运行,默认设置为 GTK3。可以通过设置以下属性来覆盖此默认设置:

jdk.gtk.version=2.2

HiDPI

根据 GUI 框架,可以使用不同的方法启用 HiDPI#Java 应用程序

更好的 2D 性能

切换到基于 OpenGL 的硬件加速管道将提高 2D 性能:

export JDK_JAVA_OPTIONS='-Dsun.java2d.opengl=true'
注意: 启用此选项可能会导致 JetBrains IDE 等软件的 UI 行为异常,使其部分绘制窗口、弹出窗口和工具栏。