Java
摘自維基百科中的 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。
OpenJDK GA — Latest OpenJDK General-Availability Release build from Oracle.
OpenJDK EA — Latest OpenJDK Early-Access build for development version from Oracle.
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 GA — Latest OpenJFX General-Availability Release build from Gluon.
OpenJFX EA — Latest OpenJFX Early-Access build for development version from Gluon.
其他實現[編輯 | 編輯原始碼]
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.
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.
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
bin32-
找到,如bin32-jreAUR。其使用java32-runtime-commonAUR,功能與java-runtime-common包相同,但添加了32
的後綴,如java32
。java32-environment-commonAUR也是同理,只有32位的JDK包使用它。開發工具[編輯 | 編輯原始碼]
對於集成開發環境,見List of applications#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
- 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
在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方案。如果要這樣的話,這些包應該:
- 把所有文件放在
/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 file list 它的手冊頁用-openjdk8
做後綴) - 不要定義任何 衝突 和替代 ,用其他的JDK,
java-runtime
,java-runtime-headless
和java-environment
- 在安裝函數 裡使用
archlinux-java
腳本以將Java環境設置為默認 如果沒有其他可用的Java環境準備設置的話 (即: 這些包不應該 強制 被裝為默認)。查閱 officially supported Java environment package sources[失效連結 2022-09-18 ⓘ] 做例子
同時也要注意:
- 包需要的任何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渲染問題。嘗試設置 "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
可能會有幫助。 - 對於sway,
export _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[編輯 | 編輯原始碼]
可能的問題和解決方法:
- 沒有GTK2。安裝gtk2包。
- 沒有OpenJFX。安裝java-openjfx包。
提示和技巧[編輯 | 編輯原始碼]
大多數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可以使用不同的方法啟用。
更好的2D性能[編輯 | 編輯原始碼]
切換到基於OpenGL的硬體加速管道可以提高2D性能:
export _JAVA_OPTIONS='-Dsun.java2d.opengl=true'