Java in Linux - root 和非 root 的不同外观和感觉 类
Java in Linux - different look and feel classes for root and non-root
我注意到 Java 为根用户和非根用户提出了不同的外观 类。我试图了解如何使 LAF 保持一致。此外,即使在 user/root 中也不一致:取决于 user/root 的登录方式:
示例代码(在laf.jar
编译打包):
import javax.swing.UIManager;
public class laf {
public static void main(java.lang.String[] args) {
try {
System.out.print(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
}
}
场景 1 以普通用户身份登录机器(在 GUI 模式下)
示例输出(如用户)
[xxx@yyy Downloads]$ java -classpath laf.jar laf
com.sun.java.swing.plaf.gtk.GTKLookAndFeel
示例输出(通过 su
切换到 root)
[root@yyy Downloads]# java -classpath ./laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
场景 2 以 root 身份登录机器(在 GUI 模式下)
示例输出(如root)
[root@yyy Downloads]# java -classpath ./laf.jar laf
com.sun.java.swing.plaf.gtk.GTKLookAndFeel
场景 3 以普通用户身份通过 SSH 登录机器(类似于上面的场景 #1,但在本例中 -相同的 LAF)
示例输出(如用户)
[xxx@yyy Downloads]$ java -classpath laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
示例输出(切换到 root)
[root@yyy Downloads]# java -classpath ./laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
软件版本:
[root@yyy Downloads]# java -version
java version "1.7.0"
Java(TM) SE Runtime Environment (build pxa6470sr9fp10-20150708_01(SR9 FP10))
IBM J9 VM (build 2.6, JRE 1.7.0 Linux amd64-64 Compressed References 20150701_255667 (JIT enabled, AOT enabled)
J9VM - R26_Java726_SR9_20150701_0050_B255667
JIT - tr.r11_20150626_95120.01
GC - R26_Java726_SR9_20150701_0050_B255667_CMPRSS
J9CL - 20150701_255667)
JCL - 20150628_01 based on Oracle jdk7u85-b15
[root@yyy Downloads]# cat /etc/redhat-release
Red Hat Enterprise Linux Workstation release 6.7 (Santiago)
getSystemLookAndFeelClassName
的第一行是:
public static String getSystemLookAndFeelClassName() {
String systemLAF = AccessController.doPrivileged(
new GetPropertyAction("swing.systemlaf"));
所以可以使用用户的JAVA_OPTS来设置
-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel
默认。
将此添加到 .rc
- 用户的文件:
set JAVA_OPTS=-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel
export JAVA_OPTS
此致
这不是关于 root,更多是关于环境变量。
基本上,UIManager.getSystemLookAndFeelClassName
方法是这样工作的:
- 检查
swing.systemlaf
系统 属性。这允许用户覆盖系统想要选择的任何内容。如果它不为空,则使用它。
- 否则,如果操作系统是Windows,它returns
WindowsLookAndFeel
。
- 否则,它会检查
sun.desktop
属性。如果 sun.desktop
设置为 gnome
,并且 GTK 是本地可用的,它返回 GTKLookAndFeel
- 否则,检查 Mac OS X 和 Solaris 以及 returns 这些操作系统的适当值。
- 如果所有其他检查均失败,则 returns "cross platform" L&F,即
MetalLookAndFeel
。
所以,与Linux/Unix相关的部分是检查sun.desktop
的部分。这个 属性 是在 JVM 启动时设置的。如果环境变量 GNOME_DESKTOP_SESSION_ID
存在,则设置为 gnome
,忽略其内容,否则设置为 null。我相信 this is the pertinent native source code 可以做到这一点。
因此,在 Linux,如果设置了该环境变量(并且 GTK 可用),您的 L&F 将设置为 GTKLookAndFeel
。如果没有,它将被设置为 MetalLookAndFeel
.
当您使用桌面管理器登录到基于 Gnome 的 Linux 时,您的环境将设置该变量。但是su
命令默认不传播环境变量。因此,当您对任何用户(不一定是 root)执行 su 时,您将丢失 GNOME_DESKTOP_SESSION_ID
环境变量,并且 Java 将默认为 MetalLookAndFeel
.
您可以使用 su -p
使您的环境通过 su
,或者如果您使用 sudo
,则使用 sudo -E
。
ssh
命令与 su
和 sudo
一样,不会传播环境变量。这也可以使用 ~/.ssh/environment
.
解决
但是,如前所述 - 您可以通过将 -Dswing.systemlaf=...
开关传递给 java 命令来轻松强制执行特定的 L&F。
我注意到 Java 为根用户和非根用户提出了不同的外观 类。我试图了解如何使 LAF 保持一致。此外,即使在 user/root 中也不一致:取决于 user/root 的登录方式:
示例代码(在laf.jar
编译打包):
import javax.swing.UIManager;
public class laf {
public static void main(java.lang.String[] args) {
try {
System.out.print(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
}
}
场景 1 以普通用户身份登录机器(在 GUI 模式下)
示例输出(如用户)
[xxx@yyy Downloads]$ java -classpath laf.jar laf
com.sun.java.swing.plaf.gtk.GTKLookAndFeel
示例输出(通过 su
切换到 root)
[root@yyy Downloads]# java -classpath ./laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
场景 2 以 root 身份登录机器(在 GUI 模式下)
示例输出(如root)
[root@yyy Downloads]# java -classpath ./laf.jar laf
com.sun.java.swing.plaf.gtk.GTKLookAndFeel
场景 3 以普通用户身份通过 SSH 登录机器(类似于上面的场景 #1,但在本例中 -相同的 LAF)
示例输出(如用户)
[xxx@yyy Downloads]$ java -classpath laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
示例输出(切换到 root)
[root@yyy Downloads]# java -classpath ./laf.jar laf
javax.swing.plaf.metal.MetalLookAndFeel
软件版本:
[root@yyy Downloads]# java -version
java version "1.7.0"
Java(TM) SE Runtime Environment (build pxa6470sr9fp10-20150708_01(SR9 FP10))
IBM J9 VM (build 2.6, JRE 1.7.0 Linux amd64-64 Compressed References 20150701_255667 (JIT enabled, AOT enabled)
J9VM - R26_Java726_SR9_20150701_0050_B255667
JIT - tr.r11_20150626_95120.01
GC - R26_Java726_SR9_20150701_0050_B255667_CMPRSS
J9CL - 20150701_255667)
JCL - 20150628_01 based on Oracle jdk7u85-b15
[root@yyy Downloads]# cat /etc/redhat-release
Red Hat Enterprise Linux Workstation release 6.7 (Santiago)
getSystemLookAndFeelClassName
的第一行是:
public static String getSystemLookAndFeelClassName() {
String systemLAF = AccessController.doPrivileged(
new GetPropertyAction("swing.systemlaf"));
所以可以使用用户的JAVA_OPTS来设置
-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel
默认。
将此添加到 .rc
- 用户的文件:
set JAVA_OPTS=-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel
export JAVA_OPTS
此致
这不是关于 root,更多是关于环境变量。
基本上,UIManager.getSystemLookAndFeelClassName
方法是这样工作的:
- 检查
swing.systemlaf
系统 属性。这允许用户覆盖系统想要选择的任何内容。如果它不为空,则使用它。 - 否则,如果操作系统是Windows,它returns
WindowsLookAndFeel
。 - 否则,它会检查
sun.desktop
属性。如果sun.desktop
设置为gnome
,并且 GTK 是本地可用的,它返回GTKLookAndFeel
- 否则,检查 Mac OS X 和 Solaris 以及 returns 这些操作系统的适当值。
- 如果所有其他检查均失败,则 returns "cross platform" L&F,即
MetalLookAndFeel
。
所以,与Linux/Unix相关的部分是检查sun.desktop
的部分。这个 属性 是在 JVM 启动时设置的。如果环境变量 GNOME_DESKTOP_SESSION_ID
存在,则设置为 gnome
,忽略其内容,否则设置为 null。我相信 this is the pertinent native source code 可以做到这一点。
因此,在 Linux,如果设置了该环境变量(并且 GTK 可用),您的 L&F 将设置为 GTKLookAndFeel
。如果没有,它将被设置为 MetalLookAndFeel
.
当您使用桌面管理器登录到基于 Gnome 的 Linux 时,您的环境将设置该变量。但是su
命令默认不传播环境变量。因此,当您对任何用户(不一定是 root)执行 su 时,您将丢失 GNOME_DESKTOP_SESSION_ID
环境变量,并且 Java 将默认为 MetalLookAndFeel
.
您可以使用 su -p
使您的环境通过 su
,或者如果您使用 sudo
,则使用 sudo -E
。
ssh
命令与 su
和 sudo
一样,不会传播环境变量。这也可以使用 ~/.ssh/environment
.
但是,如前所述 - 您可以通过将 -Dswing.systemlaf=...
开关传递给 java 命令来轻松强制执行特定的 L&F。