出自 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出現問題,如只繪製部分繪製窗口、彈出窗口和工具欄。

另見