Java (简体中文)

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
翻译状态:本文是 Java翻译。上次翻译日期:2019-03-14。如果英文版本有所更改,则您可以帮助同步翻译。

Tango-preferences-desktop-locale.png本文或本节需要翻译。要贡献翻译,请访问简体中文翻译团队Tango-preferences-desktop-locale.png

附注: 机器翻译严重,而且前后文不搭调,有语义错误。(在 Talk:Java (简体中文)# 中讨论)

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

Java是由最早由Sun微系统公司开发并在1995年作为Sun微系统Java平台的核心组件发布的编程语言。它很多语法是从C和C++派生出来的,但对象模型更简介,底层组件更少。Java的应用一般被编译成能在任何Java虚拟机(JVM),而不是特定架构上运行的字节码。

Arch Linux官方支持开源的第7、8、11和17版的 OpenJDK。这些JVM可以并存,并能够通过帮助脚本archlinux-java切换。在 Arch User Repository (简体中文)中也有一些其他的,不被官方支持的可用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)的开源实现(Java SE).

Headless JRE
最小的Java运行环境 - 需要被用来执行非GUI的Java程序.
Full JRE
完全的Java运行环境 - 需要用来运行JavaGUI程序,依赖于headless JRE.
JDK
Java Development Kit - 需要用来搭建Java开发环境, 依赖于 full JRE.
版本 Headless JRE Full JRE JDK 文献 来源
OpenJDK 17 jre-openjdk-headless jre-openjdk jdk-openjdk openjdk-doc openjdk-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 7 jre7-openjdk-headless[损坏的链接:package not found] jre7-openjdk[损坏的链接:package not found] jdk7-openjdk[损坏的链接:package not found] openjdk7-doc[损坏的链接:package not found] openjdk7-src[损坏的链接:package not found]

IcedTea-Web — Java web第一步 但是是一个被弃用的Java浏览器插件.

https://icedtea.classpath.org/wiki/IcedTea-Web[失效链接 2021-06-10 ⓘ] || icedtea-web

OpenJFX 8 — JavaFX的开源实现. 你不需要 安装这个包,如果你使用Java SE的话 (下面要讲的Oracle的JRE和JDK实现). 这个包仅仅是因为担心Java开源实现的用户 (OpenJDK 项目).

https://openjdk.java.net/projects/openjfx/ || java-openjfx, java-openjfx-doc, java-openjfx-src

OpenJDK EA — Oracle的OpenJDK为最新开发版本的早期接入.

https://jdk.java.net || openjdk-develAUR[损坏的链接:package not found]

OpenJFX EA — Oracle的OpenJFK为最新开发版本的早期接入.

https://jdk.java.net/openjfx/ || java-openjfx-develAUR[损坏的链接:package not found]

其他实现

Java SE — Oracle的JRE和JDK实现.

https://www.oracle.com/technetwork/java/javase/downloads/index.html || jreAUR jre9AUR jre8AUR jre7AUR jre6AUR jdkAUR jdk9AUR jdk8AUR jdk7AUR jdk6AUR jdk5AUR jdk-develAUR

OpenJ9 — Eclipse的JRE实现,由IBM贡献

https://www.eclipse.org/openj9/ || jdk9-openj9-binAUR jdk8-openj9-binAUR

IBM J9 — IBM的第八版Java实现.

https://developer.ibm.com/javasdk/ || jdk8-j9-binAUR jdk7-j9-binAUR jdk7r1-j9-binAUR

Parrot VM — 一个对Java [1]提供实验支持的虚拟机 ,通过两种方式,一种是 Java VM bytecode translator,另一种是Java compiler targeting the Parrot VM.

http://www.parrot.org/ || parrotAUR
注意: 32比特版本的JavaSE可以通过添加前缀 bin32-来找到,例如 bin32-jreAURbin32-jdkAUR[损坏的链接:package not found]. 他们使用的是 java32-runtime-commonAUR,而这和 java-runtime-common功能一样只要添加后缀就好了32, 例如. java32. 同样的方法也适用于 java32-environment-commonAUR,它只用于32比特版本的JDK包.

开发工具

对于集成开发环境,查阅List of applications#Integrated development environments 和特定的 Java IDEs 的子分区

为了阻止逆向工程,可以使用像proguardAUR的混淆器.

反编译器

  • Bytecode Viewer — Java逆向工程套件, 包括一个反编译器, 编辑器和调试器.
https://bytecodeviewer.com || bytecode-viewerAUR
  • CFR — Java反编译器,支持Java 9,10和更高版本的现代功能
https://www.benf.org/other/cfr/ || cfrAUR
  • Fernflower — Java的分析反编译器, 被开发为IntelliJ IDEA的一部分.
https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine || fernflower-gitAUR
  • JAD — 不被维护的Java反编译器.
https://varaneckas.com/jad || jad
https://github.com/nviennot/jd-core-java || jd-core-javaAUR
  • Krakatau — Java的反编译器,汇编器和反汇编器.
https://github.com/Storyyeller/Krakatau || krakatau-gitAUR
  • Procyon decompiler — 实验性质的Java反编译器, 被ILSpy and Mono.Cecil启发.
https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler || procyon-decompilerAUR, GUI: 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.同时前面的输出表示只有OpenJDK8的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版本的程序

如果你想运行其它版本而不是默认版本的程序(例如你有JRE7和JRE8同时装在系统里), 你可以把你的程序打包进一个小bash脚本里来暂时改变Java的默认版本。例如如果默认版本是JRE7而你想用JRE8:

#!/bin/sh 

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

包支持archlinux-java的先决条件

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

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

同时也该注意到:

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

故障排除

MySQL

因为JDBC-驱动经常使用URL的端口来建立到数据库的连接, 所以通过 "远程" (i.e., MySQL不会根据默认设置监听端口)的办法应该被考虑,尽管它们可能运行在同一个主机上, 所有, 要用JDBC和MySQL的话你应该启用到MySQL的远程连接,, 在MariaDB#Grant remote access查询指导.

IntelliJ IDEA

如果你在设置JDK的时候选择了系统的JDK,同时碰到了错误提示 `The selected directory is not a valid home for JDK`,这个时候你需要重新安装一个jdk,在IntelliJ IDEA设置jdk的时候选择新安装的JDK.

冒充另一个窗口管理器

你可以使用 wmname ,从 suckless.org下载,来使JVM相信你是在运行一个不同的窗口管理器. 这可以解决在窗口管理器发生的Java GUIs渲染问题, 比如说 awesome (简体中文) 或者 Dwm (简体中文) 或者 Ratpoison (简体中文).

$ wmname LG3D

你必须在运行了这条命令后重启有问题的程序.

这个能起作用是因为JVM包含了一个已知的、非重新父母窗口管理器的硬编码名单. 为了最大化反讽效果,一些用户喜欢冒充 LG3D, 一种非重新父母窗口管理器 由Sun公司用Java写成.

难以辨认的字体

除了下述的建议 #更好的字体渲染, 可能还是有一些字体难以辨认. 如果是这样的话,有一个很好的机会能用Microsoft的字体. 在AUR安装ttf-ms-fontsAUR .

一些应用缺少文字

如果一些应用完全没有文字,你可以用下面的办法#建议和技巧 它在FS#40871里被建议.

应用未调整WM大小,菜单快速关闭

标准Java GUI工具包有一个非重新父母窗口管理器的硬编码名单. 如果你使用的不在名单里, 运行一些Java 程序就可能产生一些问题. 最普遍的一个问题是 "灰斑", 这发生在Java程序渲染纯灰色的盒子而不是渲染GUI的时候. 另一个问题是菜单会响应你的点击,但是立马关闭.

有很多事能帮到忙:

  • 对于 jre7-openjdk[损坏的链接:package not found] 或者 jre8-openjdk, 在 /etc/profile.d/jre.sh文件里加入一行 export _JAVA_AWT_WM_NONREPARENTING=1 . 然后,用source命令处理 /etc/profile.d/jre.sh 或者重新登出登录.
  • 对于 Oracle 的 JRE/JDK, 用 SetWMName. 然而,当使用XMonad.Hooks.EwmhDesktops的时候它的作用可能被取消. 这种情况下,添加
>> setWMName "LG3D"

LogHook 可以起作用.

查阅[2] 可以获取更多信息.

当调试JavaFX程序的时候系统卡住

当你调试JavaFX程序的时候系统卡住了,你可以尝试提供JVM以下选项 -Dsun.awt.disablegrab=true.

查阅 https://bugs.java.com/view_bug.do?bug_id=6714678[失效链接 2021-11-12 ⓘ]

JavaFX 的 MediaPlayer 构造函数抛出了一个 exception

从JavaFX声音模板里创造 MediaPlayer 类的实例可能会抛出下面的exception (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.

查阅 https://www.reddit.com/r/archlinux/comments/70o8o6/using_a_javafx_mediaplayer_in_arch/

Java程序无法打开外部链接

如果Java程序不能打开链接到, 比如说, 你的浏览器, 安装gvfs.这是 Desktop.Action.BROWSE 方法所必须的. 查阅 [3]

建议和技巧

注意: 这个区里提的建议在所有程序里有用,如果你用的是明确的安装的 (外部) Java 运行的话.一些程序是用个人的 (私有的) Java运行或者是自己的GUI机制, 字体渲染机制, 等等., 这样的话下面写的都不保证能起作用.

大多数Java程序的行为都可以通过向Java运行提供预定义变量来操控. 查阅 this forum post, 一种这样做的方法包括添加下面的行到你的 ~/.bashrc文件 (或者通过 /etc/profile.d/jre.sh 来影响不是通过用source命令处理~/.bashrc来运行的程序 , 比如., 用Gnome应用师徒来运行程序):

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

比如,用系统的抗锯齿字体来使swing有GTK的视觉效果和感觉:

export _JAVA_OPTIONS='-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel'

更好的字体渲染

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

查阅 Java Runtime Environment fonts 来获取更多信息.

禁止命令行的 'Picked up _JAVA_OPTIONS' 消息

设置 _JAVA_OPTIONS 环境变量使 java (openjdk) 写入以下形式的stderr消息: 'Picked up _JAVA_OPTIONS=...'. 要在终端中禁止这些消息,可以取消设置shell启动文件中的环境变量,并使用别名java来传递与命令行参数相同的选项:

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

GTK 视觉效果和感觉

如果你的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的外观和感觉是与GTK2链接的,但是同时许多更新的桌面程序用的是GTK3. 这种GTK版本间的不兼容性可能打断程序使用Java的GUI插件,因为同一个进程里GTK2和GTK3的混合不被支持 (例如, LibreOffice 5.0).

Java 9以来, GTK的外观和感觉可以和GTK的版本 2, 2.23一起运行, 默认GTK2. 这可以通过设置下面的属性来覆盖:

jdk.gtk.version=3

更好的2D性能

切换到基于OpenGL的硬件加速管道会提升2D性能

export _JAVA_OPTIONS='-Dsun.java2d.opengl=true'
注意: 开启这项选项会导致像Jetbrains的IDE这样的软件的UI表现不正常, 让它们的窗口、弹窗和工具栏只画一部分.

非重新父母窗口管理器 / 灰色窗口 / 程序被绘制得不恰当

非重新父母窗口管理器的用户应该在他们的 .xinitrc里设置以下环境变量

export _JAVA_AWT_WM_NONREPARENTING=1

不设置这个的话会导致Java程序被绘制得不恰当.

参阅