Java:System.getProperty("user.home") 返回“?”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1503284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:33:24  来源:igfitidea点击:

Java: System.getProperty("user.home") returns "?"

javakubuntu

提问by digitalbreed

I'm completely lost on this one: System.getProperty("user.home")and System.getProperty("user.name")returns a questionmark "?".

我完全迷失在这个:System.getProperty("user.home")System.getProperty("user.name")返回一个问号“?”。

System-Specs:
Kubuntu 9.04
Gnome 2.2.61
Java 1.5.0_16

My testcase looks like that:

我的测试用例是这样的:

$ more Test.java
class Test { public static void main( String[] args ) { System.out.println( System.getProperties() ); } }

The result is (added line-breaks for better readability, replaced company name and own name):

结果是(添加换行符以提高可读性,替换公司名称和自己的名称):

$ javac Test.java
$ java Test
{
java.runtime.name=Java(TM) 2 Runtime Environment, Standard Edition,
sun.boot.library.path=/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/i386,
java.vm.version=1.5.0_16-b02,
java.vm.vendor=Sun Microsystems Inc.,
java.vendor.url=http://java.sun.com/,
path.separator=:,
java.vm.name=Java HotSpot(TM) Server VM,
file.encoding.pkg=sun.io,
sun.java.launcher=SUN_STANDARD,
user.country=US,
sun.os.patch.level=unknown,
java.vm.specification.name=Java Virtual Machine Specification,
user.dir=/home/MYCOMPANY/myname/temp,
java.runtime.version=1.5.0_16-b02,
java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment,
java.endorsed.dirs=/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/endorsed,
os.arch=i386,
java.io.tmpdir=/tmp,
line.separator=
,
java.vm.specification.vendor=Sun Microsystems Inc.,
os.name=Linux,
sun.jnu.encoding=UTF-8,
java.library.path=/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/i386/server:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/i386:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/../lib/i386,
java.specification.name=Java Platform API Specification,
java.class.version=49.0,
sun.management.compiler=HotSpot Server Compiler,
os.version=2.6.28-15-generic,
user.home=?,
user.timezone=,
java.awt.printerjob=sun.print.PSPrinterJob,
file.encoding=UTF-8,
java.specification.version=1.5,
java.class.path=.,
user.name=?,
java.vm.specification.version=1.0,
java.home=/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre,
sun.arch.data.model=32,
user.language=en,
java.specification.vendor=Sun Microsystems Inc.,
java.vm.info=mixed mode,
java.version=1.5.0_16,
java.ext.dirs=/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/ext,
sun.boot.class.path=/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/rt.jar:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/i18n.jar:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/sunrsasign.jar:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/jsse.jar:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/jce.jar:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/lib/charsets.jar:/home/MYCOMPANY/myname/apps/jdk1.5.0_16/jre/classes,
java.vendor=Sun Microsystems Inc.,
file.separator=/,
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport.cgi,
sun.io.unicode.encoding=UnicodeLittle,
sun.cpu.endian=little,
sun.desktop=gnome,
sun.cpu.isalist=
}

Did someone ever experience that? Where is Java looking to find the user and home directory? I already checked the HOME environment variable which is set correctly.

有人经历过吗?Java 在哪里寻找用户和主目录?我已经检查了正确设置的 HOME 环境变量。

采纳答案by digitalbreed

It's a bit embarrassing but the solution was simply to use a 64-bit JDK on a 64-bit system. I copied everything from my old machine, which meant also a 32-bit JDK, and this was the problem. It worked as expected with a 64-bit runtime.

这有点尴尬,但解决方案只是在 64 位系统上使用 64 位 JDK。我从旧机器上复制了所有内容,这也意味着 32 位 JDK,这就是问题所在。它在 64 位运行时按预期工作。

Sorry for bothering.

抱歉打扰了。

回答by Grzegorz Oledzki

That's really interesting. Looks like user.homeproperty is not taken from $HOME environment variable. I've tried this:

这真的很有趣。看起来user.home属性不是从 $HOME 环境变量中获取的。我试过这个:

$ echo $HOME && java Test && unset HOME && echo $HOME && java Test
/home/grzole
/home/grzole

/home/grzole

Note that the shell forgets the HOME variable value, but Java doesn't.

请注意,shell 会忘记 HOME 变量值,但 Java 不会。

EDIT: I suspect Java just takes the /home/prefix and adds the user name. Consider this:

编辑:我怀疑 Java 只是采用/home/前缀并添加用户名。考虑一下:

# adduser b
...
# rm -fr /home/b
# su - b
No directory, logging in with HOME=/
$ cd /tmp/jb
$ java Test
/home/b

Maybe you don't have the /homedirectory in your file system at all?

也许您/home的文件系统中根本没有该目录?

回答by Billy Bob Bain

A workaround, not a solution. You should be able to set it with by adding -Duser.home=$HOMEas an argument.

一种解决方法,而不是解决方案。您应该可以通过添加-Duser.home=$HOME作为参数来设置它。

java -Duser.home=$HOME Test

回答by CPerkins

What about the other guaranteed properties? What happens if you make a call to something like the following?

其他保证属性呢?如果您拨打以下电话,会发生什么?


   public static void printAllGuaranteedProperties() {
       printAProperty ("java.version", "Java version number");
       printAProperty ("java.vendor", "Java vendor specific string");
       printAProperty ("java.vendor.url", "Java vendor URL");
       printAProperty ("java.home", "Java installation directory");
       printAProperty ("java.class.version", "Java class version number");
       printAProperty ("java.class.path", "Java classpath");
       printAProperty ("os.name", "Operating System Name");
       printAProperty ("os.arch", "Operating System Architecture");
       printAProperty ("os.version", "Operating System Version");
       printAProperty ("file.separator", "File separator");
       printAProperty ("path.separator", "Path separator");
       printAProperty ("line.separator", "Line separator");
       printAProperty ("user.name", "User account name");
       printAProperty ("user.home", "User home directory");
       printAProperty ("user.dir", "User's current working directory");
    }
    public static void printAProperty (String propName, String desc) {
       System.out.println ("Value for '" + desc + "' is '" + System.getProperty(propName) + "'.");
    }

回答by Grzegorz Oledzki

wds is right in his/her comment. The user.homevalue seems to be taken from /etc/passwd. What is your line in /etc/passwdfor your user?

wds 在他/她的评论中是正确的。该user.home值似乎取自 /etc/passwd。你/etc/passwd对你的用户有什么要求?

If I changed the entry to /home/nonexisting, the Testclass printed /home/nonexisting. Do you happen to have ?in /etc/passwd?

如果我将条目更改为/home/nonexisting,则Test该类会打印/home/nonexisting. 你碰巧?在/etc/passwd 中有吗?

回答by whatnick

Need to pore through the native code to figure out what exactly is happening. The user.home variable is set by the "PAM" modules in Linux systems and if the module in use generates these dynamically and the Java implementation is trying to get the value without explicitly using PAM then the behaviour is unpredictable hence the "?"

需要仔细研究本机代码以弄清楚到底发生了什么。user.home 变量由 Linux 系统中的“PAM”模块设置,如果正在使用的模块动态生成这些并且 Java 实现试图在不显式使用 PAM 的情况下获取该值,则行为是不可预测的,因此“?”

回答by Ogre Psalm33

For completeness, it also looks like, if the system in question is configured to use LDAP authentication (and not /etc/passwd), then the issue outlined in this bug report may be the problem: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6972329. Make sure the appropriate libnss_ldap.so is installed for your system (e.g.: a 32-bit LDAP library for use with a 32-bit Java). Some commands that might be helpful for determining this might be:

为了完整起见,如果有问题的系统配置为使用 LDAP 身份验证(而不是 /etc/passwd),那么此错误报告中概述的问题可能是问题:http: //bugs.java.com /bugdatabase/view_bug.do?bug_id=6972329。确保为您的系统安装了适当的 libnss_ldap.so(例如:用于 32 位 Java 的 32 位 LDAP 库)。可能有助于确定这一点的一些命令可能是:

> rpm -qa | grep ldap
nss-pam-ldapd-0.7.5-14.el6_2.1.x86_64   # Note x86_64 bit version installed

> ls -l /lib64/libnss_ldap*
-rwxr-xr-x. 1 root root 44328 Jan  3  2012 /lib64/libnss_ldap.so.2
# ^^^ note 64 bit version installed.

> ls /lib/libnss_ldap*
ls: cannot access /lib/libnss_ldap*: No such file or directory
# ^^^ Indicates 32 bit version is not installed!

回答by Steffen Kux

I had the same problem. As mentioned above, the problem is, that the 32 bit Java needs also the 32 bit ldap libraries to be installed. If not, the decribed error occurs.

我有同样的问题。如上所述,问题是,32 位 Java 还需要安装 32 位 ldap 库。如果不是,则发生所描述的错误。

Installing the libnss_ldap.so.2 and the depending packages solves the problem.

安装 libnss_ldap.so.2 和依赖包解决了这个问题。