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。
版本 Headless JRE Full JRE JDK 文獻 源碼
OpenJDK 21 jre-openjdk-headless jre-openjdk jdk-openjdk openjdk-doc openjdk-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 — Latest OpenJDK General-Availability Release build from Oracle.

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

OpenJDK EA — Latest OpenJDK Early-Access build for development version from Oracle.

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

IcedTea-Web — Java Web Start and the deprecated Java browser plugin.

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

OpenJFX[編輯 | 編輯原始碼]

OpenJFX is the open-source implementation of JavaFX. You do not need to install this package if you are using Oracle JDK. This package only concerns users of the open source implementation of Java (OpenJDK project), and its derivatives.

版本 運行環境與開發 文檔 源碼
OpenJFX 20 java-openjfxAUR java-openjfx-docAUR java-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出現問題,如只繪製部分繪製窗口、彈出窗口和工具欄。

另見[編輯 | 編輯原始碼]