Java: System.getProperty( "user.home" ) возвращает "?"
Я полностью потерял это: 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, которая установлена правильно.
Ответы
Ответ 1
Это немного неловко, но решение было просто использовать 64-битный JDK в 64-битной системе. Я скопировал все с моей старой машины, что означало также 32-битный JDK, и это была проблема. Он работал, как ожидалось, с 64-битной средой выполнения.
Извините за беспокойство.
Ответ 2
Обходной путь, а не решение. Вы должны установить его, добавив -Duser.home=$HOME
в качестве аргумента.
java -Duser.home=$HOME Test
Ответ 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 current working directory");
}
public static void printAProperty (String propName, String desc) {
System.out.println ("Value for '" + desc + "' is '" + System.getProperty(propName) + "'.");
}
Ответ 4
wds находится прямо в его комментарии. Значение user.home
, по-видимому, берется из /etc/passwd.
Какова ваша строка в /etc/passwd
для вашего пользователя?
Если я изменил запись на /home/nonexisting
, класс Test
напечатал /home/nonexisting
. У вас есть ?
в/etc/passwd?
Ответ 5
Это действительно интересно. Похоже, что свойство user.home
не берется из переменной среды HOME.
Я пробовал это:
$ echo $HOME && java Test && unset HOME && echo $HOME && java Test
/home/grzole
/home/grzole
/home/grzole
Обратите внимание, что оболочка забывает значение переменной HOME, но Java не делает.
EDIT:
Я подозреваю, что Java просто берет префикс /home/
и добавляет имя пользователя.
Рассмотрим это:
# adduser b
...
# rm -fr /home/b
# su - b
No directory, logging in with HOME=/
$ cd /tmp/jb
$ java Test
/home/b
Может быть, у вас нет каталога /home
в вашей файловой системе?
Ответ 6
Нужно просыпаться через собственный код, чтобы выяснить, что именно происходит. Переменная user.home устанавливается модулями "PAM" в системах Linux, и если используемый модуль генерирует их динамически, и реализация Java пытается получить значение без явного использования PAM, тогда поведение непредсказуемо, следовательно, "?"
Ответ 7
Для полноты, похоже, что если рассматриваемая система настроена на использование аутентификации LDAP (а не /etc/passwd ), то проблема, описанная в этом отчете об ошибке, может быть проблемой: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6972329. Убедитесь, что для вашей системы установлен соответствующий libnss_ldap.so(например, 32-разрядная библиотека LDAP для использования с 32-разрядной Java). Некоторые команды, которые могут быть полезны для определения этого, могут быть:
> 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!
Ответ 8
У меня была та же проблема. Как упоминалось выше, проблема в том, что 32-разрядная Java нуждается также в 32-битных библиотеках ldap для установки. Если нет, возникает описанная ошибка.
Установка libnss_ldap.so.2 и зависимых пакетов решает проблему.