跳转至内容

Java

来自 ArchWiki
(重定向自 OpenJDK)

来自 维基百科

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环境可用,但不受官方支持。

安装

  • 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源代码构建的。

无头JRE
最小的Java运行时环境—用于执行非GUI Java程序。
完整JRE
完整的Java运行时环境—用于执行GUI Java程序。
JDK
Java开发工具包—用于Java开发。

JDK、完整JRE和无头JRE相互冲突,因为较小的包是子集。

  • JDK冲突并提供完整JRE,
  • 完整JRE冲突并提供无头JRE。
版本 无头JRE 完整JRE JDK 文档
OpenJDK 25 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 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。
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


提示 Oracle JDK 的 32 位版本可以通过添加前缀 bin32- 来找到,例如 bin32-jreAUR。它们使用 java32-runtime-commonAUR,其功能相当于通过添加后缀 32 来实现 java-runtime-common,例如 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

GUI前端

  • 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环境,该命令将查找有效的环境并尝试为您设置。官方支持的包“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-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冲突替换
  • install函数中使用脚本archlinux-java将Java环境设置为默认值,前提是尚无其他有效的Java环境被设置(即:包不应强制设置为默认值)。例如,请参阅官方支持的Java环境包源

另请注意,

  • 需要任何Java环境的包应像往常一样声明对java-runtimejava-runtime-headlessjava-environment的依赖。
  • 需要特定Java供应商的包应声明对相应包的依赖。
  • OpenJDK包现在声明provides="java-runtime-openjdk=${pkgver}"等。这使得第三方包可以声明对OpenJDK的依赖而无需指定版本。

技巧与提示

注意 本节中的建议适用于所有使用显式安装的(外部)Java运行时环境的应用程序。某些应用程序捆绑了自己的(私有)运行时环境或使用自己的机制进行GUI、字体渲染等,因此以下内容不能保证有效。
警告 某些应用程序,例如远程JetBrains IDE,在使用以下某些设置时可能会启动失败。

大多数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 版本 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 行为异常,导致它们部分绘制窗口、弹出窗口和工具栏。

故障排除

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.orgwmname 包,让 JVM 认为您正在运行另一个窗口管理器。这可以解决 Java GUI 在 Awesome、DwmRatpoison 等窗口管理器中出现的渲染问题。这是因为 JVM 包含一个硬编码的已知非重叠窗口管理器列表。为了达到最大的讽刺效果,一些用户喜欢模拟 Sun 公司编写的非重叠窗口管理器 LG3DJava 编写的 Project Looking Glass)。尝试设置 compizMetacityLG3D

$ 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 应用程序无法打开到例如您的 Web 浏览器的链接,请安装 gvfs。这是 Desktop.Action.BROWSE 方法所必需的。请参阅 [1] 应用程序打印错误消息 java.lang.UnsupportedOperationException: The BROWSE action is not supported on the current platform! 是此问题的可靠指示。

初始化 QuantumRenderer 时出错:未找到合适的管道

可能的问题/解决方案