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 项目).
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贡献
IBM J9 — IBM的第八版Java实现.
Parrot VM — 一个对Java [1]提供实验支持的虚拟机 ,通过两种方式,一种是 Java VM bytecode translator,另一种是Java compiler targeting the Parrot VM.
- http://www.parrot.org/ || parrotAUR
bin32-
来找到,例如 bin32-jreAUR 和 bin32-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逆向工程套件, 包括一个反编译器, 编辑器和调试器.
- CFR — Java反编译器,支持Java 9,10和更高版本的现代功能
- Fernflower — Java的分析反编译器, 被开发为IntelliJ IDEA的一部分.
- https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine || fernflower-gitAUR
- JAD — 不被维护的Java反编译器.
- JD-Core-java — Java反编译器]的薄包装.
- Krakatau — Java的反编译器,汇编器和反汇编器.
- 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方案. 如果要这样的话,这些包应该:
- 把所有文件放在这里
/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 做例子
同时也该注意到:
- 包需要的 任何 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运行提供预定义变量来操控. 查阅 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.2
和 3
一起运行, 默认GTK2. 这可以通过设置下面的属性来覆盖:
jdk.gtk.version=3
更好的2D性能
切换到基于OpenGL的硬件加速管道会提升2D性能
export _JAVA_OPTIONS='-Dsun.java2d.opengl=true'
非重新父母窗口管理器 / 灰色窗口 / 程序被绘制得不恰当
非重新父母窗口管理器的用户应该在他们的 .xinitrc
里设置以下环境变量
export _JAVA_AWT_WM_NONREPARENTING=1
不设置这个的话会导致Java程序被绘制得不恰当.