Java

来自 Arch Linux 中文维基

摘自维基百科中的 Java 词条:

Java是一种编程语言,最初由Sun Microsystems开发,并于1995年作为Sun Microsystems的Java平台的核心组件发布。它有很多语法来自C和C++,但对象模型更简洁,底层组件更少。Java的应用一般会编译成能在任何Java虚拟机(JVM)而不是特定架构上运行的字节码。

Arch Linux官方支持开源的第8、11、17和21版的 OpenJDK。这些JVM可以并存,并能够通过帮助脚本archlinux-java切换。在 AUR中也有一些不受官方支持的Java环境。

安装[编辑 | 编辑源代码]

注意:
  • Arch Linux官方只支持 OpenJDK 实现。
  • 刚安装完成的Java环境还无法被Shell($PATH 变量)识别。可以在命令行中使用source命令读取/etc/profile,重启,或者注销并重新登入桌面环境来正确更新。

两个常见的包经常作为其它包的依赖,分别是 java-runtime-common (包含Java运行环境(JRE)的公共文件) 和 java-environment-common (包括Java开发包(JDK)的公共文件)。包提供的环境配置文件 /etc/profile.d/jre.sh 指向由 archlinux-java 帮助脚本设置的链接 /usr/lib/jvm/default/bin

警告: 务必使用 archlinux-java编辑 /usr/lib/jvm/default/usr/lib/jvm/default-runtime 这两个链接。

这些链接用来指示位于 /usr/lib/jvm/java-${JAVA_MAJOR_VERSION}-${VENDOR_NAME} 的默认Java运行环境,或位于 /usr/lib/jvm/java-${JAVA_MAJOR_VERSION}-${VENDOR_NAME}/jre 的Java运行环境。

大多数安装的可执行文件都以链接的形式放在 /usr/bin 中,其他可执行文件则在 $PATH 指向的位置处。/etc/profile.d/jdk.sh 已经不再在包中提供了。

OpenJDK[编辑 | 编辑源代码]

OpenJDK是Java平台标准版(Java SE)的开源实现,也是官方的参考实现。有几个OpenJDK构建的分发,如Adoptium(以前称为AdvertOpenJDK)和Amazon Corretto。Arch Linux的OpenJDK包由上游的OpenJDK源代码构建。

Headless JRE
Java的最小运行环境 - 执行非GUI的Java程序所需。
Full JRE
完全的Java运行环境 - 执行Java GUI程序所需,依赖于headless JRE。
JDK
Java Development Kit - Java开发所需,依赖于 full JRE。:JDK、JRE 和 JRE-headless 互相冲突,因为较小的包是其子集;也就是JDK 提供 JRE 并与 JRE 冲突,而 JRE 提供 JRE-headless 并与 JRE-headless 冲突。
版本 Headless JRE Full JRE JDK 文献 源码
OpenJDK23 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

OpenJDK GA — Oracle 最新的 OpenJDK 通用可用版本发布构建。

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

OpenJDK EA — Oracle 最新的 OpenJDK 开发版Early-Access构建版本。

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

OpenJDK Wakefield — JDK 在 Linux 上对 Wayland 桌面环境(WIP)支持。

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

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

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

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-openjfx java17-openjfx-doc java17-openjfx-src
OpenJFX 11 java11-openjfx java11-openjfx-doc java11-openjfx-src
OpenJFX 8 java8-openjfxAUR java8-openjfx-docAUR java8-openjfx-srcAUR

OpenJFX GA — Latest OpenJFX General-Availability Release build from Gluon.

https://openjfx.io/ || java-openjfx-binAUR

OpenJFX EA — Latest OpenJFX Early-Access build for development version from Gluon.

https://openjfx.io/ || java-openjfx-ea-binAUR

其他实现[编辑 | 编辑源代码]

Oracle JDK — Oracle's commercially licensed build of OpenJDK.Note that some versions are only available via manual download, which requires to sign the OTN agreement and create an Oracle account.

https://www.oracle.com/java/technologies/downloads/ ||

Eclipse Adoptium/Temurin — Eclipse's implementation of JRE/JDK, based on the Hotspot JVM (formerly AdoptOpenJDK). Note that the JRE is known as Eclipse Temurin.

https://adoptium.net/ || jdk-temurinAUR jdk17-temurinAUR jdk11-temurinAUR

OpenJ9 — Eclipse's implementation of JRE, contributed by IBM.

https://www.eclipse.org/openj9/ || jdk-openj9-binAUR jdk14-openj9-binAUR jdk13-openj9-binAUR jdk12-openj9-binAUR jdk11-openj9-binAUR jdk10-openj9-binAUR jdk9-openj9-binAUR jdk8-openj9-binAUR

IBM Certified — IBM Semeru Runtime Certified Edition.

https://www.ibm.com/semeru-runtimes/downloads || jdk11-j9-binAUR

IBM J9 — IBM's implementation of JRE, using OpenJ9 contributions.

https://www.ibm.com/support/pages/java-sdk-downloads || jdk8-j9-binAUR jdk7-j9-binAUR jdk7r1-j9-binAUR

Parrot VM — a VM with experimental support for Java [1] through two different methods: either as a Java VM bytecode translator, or as a Java compiler targeting the Parrot VM. Parrot is not actively developed since 2017.

http://www.parrot.org/ || parrotAUR
注意: Oracle JDK的32位版本可以通过前缀bin32-找到,如bin32-jreAUR。其使用java32-runtime-commonAUR,功能与java-runtime-common相同,但添加了32的后缀,如java32java32-environment-commonAUR也是同理,只有32位的JDK包使用它。

开发工具[编辑 | 编辑源代码]

对于集成开发环境,见List of applications#Integrated development environmentsJava IDEs子分区。

为了阻止逆向工程,可以使用proguardAUR等混淆器。

反编译器[编辑 | 编辑源代码]

  • CFR — Java decompiler, supporting modern features of Java 9, 10 and beyond.
https://www.benf.org/other/cfr/ || cfrAUR
  • Fernflower — Analytical decompiler for Java, developed as part of IntelliJ IDEA.
https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine || fernflower-gitAUR
  • Krakatau — Java decompiler, assembler, and disassembler.
https://github.com/Storyyeller/Krakatau || krakatau-gitAUR
  • Procyon decompiler — Experimental Java decompiler, inspired by ILSpy and Mono.Cecil.
https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler || procyon-decompilerAUR
  • Java Decompiler (JD-Core) — Popular Java decompiler providing a GUI (see JD-GUI) and supporting Java 1-10.
https://java-decompiler.github.io/ || jd-core-javaAUR
  • Jadx — Android DEX to Java decompiler with an optional GUI (see Jadx-GUI)
https://github.com/skylot/jadx || jadx
  • JAD — Unmaintained Java decompiler (last release 2006).
https://varaneckas.com/jad || jad

GUI前端[编辑 | 编辑源代码]

  • Bytecode Viewer — Java reverse engineering suite, including a decompiler, editor and debugger; Frontend for CFR/Fernflower/Procyon
https://bytecodeviewer.com || bytecode-viewerAUR
  • Recaf — An easy to use modern Java bytecode editor that abstracts away the complexities of Java programs; Frontend for CFR/Fernflower/Procyon
https://www.coley.software/Recaf/ || recaf-binAUR
  • Java Decompiler (JD-GUI) — Popular Java decompiler providing a GUI and supporting Java 1-10; Frontend for JD-Core
https://java-decompiler.github.io/ || jd-guiAUR
  • Jadx-GUI — Android APK DEX to Java decompiler with an optional GUI; Frontend for Jadx
https://github.com/skylot/jadx || jadx
  • Luyten — An Open Source Java Decompiler Gui; Frontend for Procyon
https://github.com/deathmarine/Luyten || luytenAUR

在JVM间切换[编辑 | 编辑源代码]

帮助脚本 archlinux-java 提供了如下功能:

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-7-openjdk (default)
  java-8-openjdk/jre

这里的(default)表示目前默认使用java-7-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启动一个程序(例如系统同时安装了Java 18和11),可以用一个bash脚本包装应用程序,在本地改变Java的默认路径。例如默认版本是Java 18,而您要使用java 11:

#!/bin/sh 

export PATH=/usr/lib/jvm/java-8-openjdk/jre/bin/:$PATH
exec /path/to/application "$@"

For a systemd service you can append JAVA_HOME to environment variables in the drop-in file:

/etc/systemd/system/unit.d/override.conf
[Service]
Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk

软件包支持archlinux-java的先决条件[编辑 | 编辑源代码]

注意: 这条信息同样适用于 archlinux32-java 的32位Java包,如果它们的包或者可执行名字里有 32 ,都可适用.

这个分区的信息针对愿意提供包作为备份JVM给 AUR 的贡献者, 并且能够用 archlinux-java集成Arch Linux JVM方案。如果要这样的话,这些包应该:

同时也要注意:

  • 包需要的任何Java环境都应声明依赖,和通常一样在java-runtimejava-runtime-headlessjava-environment里声明。
  • 包如果需要特定的Java提供商,应该在相关包里声明依赖。
  • OpenJDK 包现在应该声明 provides="java-runtime-openjdk=${pkgver}" 等。这能让第三方的包在没有特定版本要求的OpenJDK里声明依赖

疑难解答[编辑 | 编辑源代码]

MySQL[编辑 | 编辑源代码]

由于JDBC-drivers经常使用URL中的端口来建立与数据库的连接,它被认为是 “远程”的(即MySQL不会按照其默认设置监听该端口),尽管它们可能运行在同一台主机上,因此,若要使用JDBC和MySQL,应按照MariaDB#Grant remote access中的说明,启用对MySQL的远程访问。

IntelliJ IDEA[编辑 | 编辑源代码]

如果在设置JDK的时候选择了系统的JDK,同时碰到了错误提示The selected directory is not a valid home for JDK,此时应重新安装另一个JDK包,并在IDEA设置中选择它。

伪装成另一个窗口管理器[编辑 | 编辑源代码]

可以使用suckless.org中的wmname来使JVM相信其正运行于其它窗口管理器。这也许能解决在AwesomeDwmRatpoison等窗口管理器中出现的Java GUI渲染问题。尝试设置 "compiz "或 "LG3D":

$ wmname LG3D

运行了这条命令后,必须重启有问题的程序。

这种做法能够有效,是因为JVM包含了一个已知的、non-re-parenting窗口管理器的硬编码列表。

javaagent 是一个在 MATE 中看设置 wmname 的工具,可以解决 Java 程序全屏显示失败的问题。

字体难以辨认[编辑 | 编辑源代码]

除了下面#更好的字体渲染中的建议,有些字体可能依然难以辨认。使用微软的字体或许能有所改善,安装ttf-ms-fontsAUR即可。

某些应用没有文字[编辑 | 编辑源代码]

如果某些应用完全没有文字,使用FS#40871中建议的#提示和技巧下的选项可能会有所帮助。

灰色窗口/应用不随窗口管理器调整大小/菜单自动关闭[编辑 | 编辑源代码]

标准的Java GUI工具包有一个non-re-parenting窗口管理器的硬编码列表,如果使用不在该列表中的窗口管理器,在运行某些Java应用时可能会有问题。最常见的问题之一是Java应用渲染成了一个灰色盒子而不是GUI。另一个问题是菜单能够响应点击,但马上又会关闭。

以下内容也许有所帮助:

  • #伪装成另一个窗口管理器
  • 对于jre8-openjdk,在/etc/profile.d/jre.sh中添加一行export _JAVA_AWT_WM_NONREPARENTING=1,然后重新登录系统。
  • 对于最新版本的JDK,执行窗口管理器之前,在~/.xinitrc中添加一行export AWT_TOOLKIT=MToolkit
  • 对于Oracle的JRE/JDK,使用SetWMName,但当同时使用XMonad.Hooks.EwmhDesktops时可能无效。这种情况下,在>> setWMName "LG3D"中添加LogHook可能会有帮助。
  • 对于swayexport _JAVA_AWT_WM_NONREPARENTING=1可能可以解决问题。

详见[2]

调试JavaFX应用时系统卡住[编辑 | 编辑源代码]

如果调试JavaFX应用时系统卡住了,可以尝试提供JVM选项-Dsun.awt.disablegrab=true

[3]

JavaFX's MediaPlayer constructor throws an exception[编辑 | 编辑源代码]

从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以解决问题。

[4]

Java程序无法打开外部链接[编辑 | 编辑源代码]

如果Java应用无法将链接打开到浏览器等应用,请安装gvfs,因为Desktop.Action.BROWSE办法依赖于它。

[5]

Error initializing QuantumRenderer: no suitable pipeline found[编辑 | 编辑源代码]

可能的问题和解决方法:

提示和技巧[编辑 | 编辑源代码]

注意: 本节中的建议适用于所有使用明确安装(外部)的Java运行环境的应用。有些应用捆绑了自己(私有)的运行环境,或使用自己的GUI、字体渲染等机制,以下内容不一定完全适用于这种情况。

大多数Java应用的行为都可以通过向Java运行时提供预定义变量来控制。从这个论坛帖子来看,一种方法是在~/.bash_profile中添加以下一行 (或在/etc/profile.d/jre.sh添加来影响那些不通过~/.bash_profile运行的程序):

export _JAVA_OPTIONS="-D<option 1> -D<option 2>..."

例如,使用系统抗锯齿字体并使swing使用GTK的外观与体验(look and feel):

export _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。
(命令行选项) 在 "class name"参数前指定的参数是Java选项。
_JAVA_OPTIONS 旧方法,影响应用程序和工具。

更好的字体渲染[编辑 | 编辑源代码]

开源和闭源的Java实现都有不合适的抗锯齿字体实现。这可以通过以下办法来解决: -Dawt.useSystemAAFontSettings=on-Dswing.aatext=true

详见Java Runtime Environment fonts

禁止命令行里的 'Picked up _JAVA_OPTIONS' 消息[编辑 | 编辑源代码]

设置 JDK_JAVA_OPTIONS 环境变量会使Java(openjdk)向stderr写出以下形式的信息:'Picked up JDK_JAVA_OPTIONS=...'。为了禁止终端中显示这些信息,可以在~/.bashrc中取消设置环境变量,并alias java,将这些选项传递为命令行参数:

_SILENT_JAVA_OPTIONS="$_JAVA_OPTIONS"
unset _JAVA_OPTIONS
alias java='java "$_SILENT_JAVA_OPTIONS"'

非交互式的Shell,如Java程序的启动脚本,(通常)不读取~/.bashrc,但仍从其父进程中继承了导出的变量(而父进程又在某个时间从读取了~/.bash_profile的登录Shell中继承了它)。

至于这种情况,一般会在~/.bashrc的开头放一个声明,以避免读取文件。这样变量就会传递到通过桌面菜单启动的程序,如果是交互式Shell,则会使用alias来代替(这则不能用于脚本)。

GTK LookAndFeel(外观与体验)[编辑 | 编辑源代码]

如果你的Java程序看起来很丑,你可能想为swing组件设置默认外观与体验:

swing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel

一些Java程序坚持用跨平台的金属风格外观与体验。在这些情况下,你可以通过设置下面的属性强制这些app用GTK外观和外观:

swing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel

GTK3支持[编辑 | 编辑源代码]

在Java 9以前,GTK LookAndFeel是针对GTK2链接的,而许多较新的桌面应用程序使用GTK3。这种GTK版本之间的不兼容可能会破坏使用Java插件的GUI应用程序,因为在Java不支持在同一进程中混合使用GTK2和GTK3(如LibreOffice 5.0)。

GTK LookAndFeel可以针对GTK22.23运行,默认为GTK3。可以修改以下属性以调整。

jdk.gtk.version=3

HiDPI[编辑 | 编辑源代码]

根据GUI框架的不同,HiDPI#Java applications可以使用不同的方法启用。

更好的2D性能[编辑 | 编辑源代码]

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

export _JAVA_OPTIONS='-Dsun.java2d.opengl=true'
注意: 启用该选项可能会导致像JetBrains IDEs这样的软件的UI出现问题,如只绘制部分绘制窗口、弹出窗口和工具栏。

另见[编辑 | 编辑源代码]