摘自維基百科中的 Java 詞條:
- 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包 包安裝)切換。在 AUR 中也有一些不受官方支持的Java環境。
安裝
兩個常見的包分別作為依賴被拉取,分別是 java-runtime-common包(包含 Java 運行環境 的公共文件)和 java-environment-common包(包含 Java 開發工具包 的公共文件)。
提供的 /etc/profile.d/jre.sh
和 /etc/profile.d/jre.csh
文件指向由 archlinux-java 幫助腳本設置的連結 /usr/lib/jvm/default/bin
。
/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運行環境 - 執行Java GUI程序所需。
- JDK
- Java Development Kit - Java開發所需。
JDK、full JRE 和 headless JRE 互相衝突,因為較小的包是其子集:
- JDK 衝突並提供 full JRE,
- full JRE 衝突並提供 headless JRE。
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 開發版Early-Access構建版本。
OpenJDK GA — Oracle 最新的 OpenJDK 通用可用版本發布構建。
OpenJDK Wakefield — JDK 在 Linux 上對 Wayland 桌面環境(WIP)支持。
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 — 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 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 實現,基於 J9 JVM,由 IBM 貢獻。
- 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 包使用它。開發工具
對於集成開發環境,見List of applications/Utilities#Integrated development environments 和 Java IDEs 子分區。
為了阻止逆向工程,可以使用proguardAUR等混淆器。
反編譯器
- CFR — Java decompiler, supporting modern features of Java 9, 10 and beyond.
- 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
- Vineflower — Java decompiler forked from Fernflower, aiming to improve code quality. Also available as an IntelliJ IDEA plugin.
- Krakatau — Java decompiler, assembler, and disassembler.
- Procyon decompiler — Experimental Java decompiler, inspired by ILSpy and Mono.Cecil.
- Java Decompiler (JD-Core) — Popular Java decompiler providing a GUI (see JD-GUI) and supporting Java 1-10.
- Jadx — Android DEX to Java decompiler with an optional GUI (see Jadx-GUI).
- JAD — Unmaintained Java decompiler (last release 2006).
GUI前端
- Bytecode Viewer — Java reverse engineering suite, including a decompiler, editor and debugger; Frontend for CFR/Fernflower/Procyon.
- Recaf — An easy to use modern Java bytecode editor that abstracts away the complexities of Java programs; Frontend for CFR/Fernflower/Procyon.
- Java Decompiler (JD-GUI) — Popular Java decompiler providing a GUI and supporting Java 1-10; Frontend for JD-Core.
- Jadx-GUI — Android APK DEX to Java decompiler with an optional GUI; Frontend for Jadx.
- Luyten — An Open Source Java Decompiler Gui; Frontend for Procyon.
- https://github.com/deathmarine/Luyten || luytenAUR== 在JVM間切換 ==
幫助腳本 archlinux-java (軟體包: java-runtime-common包) 提供了如下功能:
archlinux-java <COMMAND> COMMAND: status 列出已安装的 Java 环境及当前启用的环境 get 返回设置为默认的 Java 环境的短名称 set <JAVA_ENV> 强制将 <JAVA_ENV> 设置为默认 unset 取消当前默认的 Java 环境 fix 修复无效/损坏的默认 Java 环境配置
列出兼容的安裝了的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啟動一個程序(例如系統同時安裝了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 file中附加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
,都可適用。這個分區的信息針對願意提供包作為備份JVM給 AUR 的貢獻者,並且能夠用 archlinux-java
集成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包 - 用
-${VENDOR_NAME}${JAVA_MAJOR_VERSION}
的格式給手冊頁添加後綴以防止衝突(查閱 jre8-openjdk包 文件列表,它的手冊頁用-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-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相信其正運行於其它窗口管理器。這也許能解決在Awesome或Dwm或Ratpoison等窗口管理器中出現的Java GUI渲染問題。這種做法能夠有效,是因為JVM包含了一個已知的、non-re-parenting窗口管理器的硬編碼列表。為了達到最大的諷刺效果,一些用戶喜歡偽裝成LG3D
,這是由Sun用Java編寫的non-re-parenting窗口管理器Project Looking Glass。嘗試設置compiz
、Metacity
或LG3D
:
$ wmname 窗口管理器名称
運行了這條命令後,必須重啟有問題的程序。
另外,可以使用javaagent JavaMatePatch,它是在MATE中設置WM名稱並解決Java Swing應用程式在全屏啟動時工作不正常的bug的工具。在Java選項中添加-javaagent:JavaMatePatch-1.0.0-SNAPSHOT.jar=窗口管理器名稱
來使用它。
字體難以辨認
除了下面#更好的字體渲染中的建議,有些字體可能依然難以辨認。使用微軟的字體或許能有所改善,安裝ttf-ms-fontsAUR即可。
某些應用沒有文字
如果某些應用完全沒有文字,使用FS#40871中建議的#提示和技巧下的選項可能會有所幫助。
灰色窗口/應用不隨窗口管理器調整大小/菜單自動關閉
標準的Java GUI工具包有一個non-re-parenting窗口管理器的硬編碼列表,如果使用不在該列表中的窗口管理器,在運行某些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
。
見[1]。
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以解決問題。如果ffmpeg-compat-55AUR無法構建,可以嘗試安裝ffmpeg3.4AUR。
見[2]。
Java程序無法打開外部連結
如果Java應用無法將連結打開到瀏覽器等應用,請安裝gvfs包,因為Desktop.Action.BROWSE
辦法依賴於它。見[3]。
如果應用程式列印錯誤消息java.lang.UnsupportedOperationException: The BROWSE action is not supported on the current platform!
,這通常是此問題的明確指示。
Error initializing QuantumRenderer: no suitable pipeline found
可能的問題和解決方法:
- 沒有GTK2。安裝gtk2包。
- 沒有OpenJFX。安裝java-openjfxAUR。
提示和技巧
大多數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可以針對GTK2
、2.2
和3
運行,默認為GTK3。可以通過設置以下屬性來調整:
jdk.gtk.version=3
HiDPI
根據GUI框架的不同,HiDPI#Java applications可以使用不同的方法啟用。