tags:

views:

2054

answers:

6

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.

A: 

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?

Grzegorz Oledzki
+2  A: 

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
Wayne Young
Yeah, I went for that way, too, renaming the original java to java_bin and creating a shell script which adds these properties to the java_bin command line. I don't want to accept this as the solution, though, because there must be a better way.
digitalbreed
What does an strace log show?strace -o foobar.log java Test
Wayne Young
A: 

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

CPerkins
A: 

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?

Grzegorz Oledzki
My user not in /etc/passwd. Same for my colleague on his machine, though, but it works there.
digitalbreed
A: 

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

whatnick
+2  A: 

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.

digitalbreed
Don't be sorry for bothering. It's a real bug in the jvm, and this post has also helped other people here on SO.
extraneon
This is http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6972329 (not confirmed as JDK bug, could be a system issue).
Pascal Thivent