Question

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

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.

Was it helpful?

Solution

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.

Sorry for bothering.

OTHER TIPS

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

java -Duser.home=$HOME Test

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

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

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

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

$ 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.

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

# 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 /home directory in your file system at all?

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 "?"

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:

> 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!

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top