34

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

System-Specs:
Kubuntu 9.04
Gnome 2.2.61
Java 1.5.0_16

我的测试用例如下所示:

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

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

$ 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=
}

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

4

10 回答 10

39

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

抱歉打扰了。

于 2009-10-02T09:39:53.287 回答
14

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

java -Duser.home=$HOME Test
于 2009-10-01T11:37:38.203 回答
3

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


   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) + "'.");
    }

于 2009-10-01T11:41:51.050 回答
3

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

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

于 2009-10-01T11:48:47.757 回答
1

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

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

/home/grzole

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

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

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

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

于 2009-10-01T11:19:32.933 回答
1

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

于 2009-10-01T13:35:43.767 回答
1

为了完整起见,如果有问题的系统配置为使用 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!
于 2014-02-03T16:28:13.510 回答
1

我遇到了同样的问题,并受到@digitalbreed 的回答的启发,我发现了一个类似但不同的解决方案。就我而言,一切都是 64 位的。但是,我注意到问题仅出在从命令行运行时,而如果我从 IntelliJ 尝试它,它工作得很好——因为它使用了不同的 JDK。

因此,我已经从 CLI ( openjdk-15.0.1-ga,由 nix-env 提供) 中删除了我正在使用的 JDK,并将 IntelliJ 的 JDK ( openjdk-16.0.1) 添加到PATH,现在一切正常。

于 2021-05-20T07:35:40.983 回答
0

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

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

于 2014-10-10T06:19:51.137 回答
0

我在运行mvndocker 镜像时遇到了这个问题,它在后台运行 java 并共享这个问题。我认为这个答案有正确的诊断,但解决方案对我不起作用。我必须.m2在两个地方安装一个本地文件夹才能让文件夹正确缓存。它想将其/root/.m2用于某些事物和/scratch/?/.m2其他事物,因此我将它们都安装了

mkdir -p root/.m2
docker run --rm -it \
  --user $(id -u):$(id -g) \
  -v `pwd`:/scratch --workdir /scratch -e HOME=/scratch \
  -v `pwd`/root:/root/ -v `pwd`/root:'/scratch/?' \
  maven:3-jdk-11 mvn package
于 2021-11-05T12:58:23.650 回答