34

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.

digitalbreed
  • 3,953
  • 4
  • 26
  • 24

10 Answers10

40

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
  • 3,953
  • 4
  • 26
  • 24
  • 19
    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 Aug 27 '10 at 21:55
  • 3
    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 Aug 27 '10 at 23:48
  • We had the same problem for a long time. After reading the bug report which @PascalThivent referenced, it was exactly our case. This problem doesnt occur on local accounts but it happens only on LDAP accounts. And the problem was 32 bit version of libnss_ldap was not installed in our system. After we installed 32 bit nss_pam_ldap package everything worked smoothly. – akifusenet Apr 22 '15 at 10:42
  • This is the best solution so far for addressing LDAP user home issues. – Venkateswara Rao Aug 03 '16 at 06:25
  • You should not be embarrassed. Your answer helped me solve similar issue. After scratching my head for hours. :) – Newbee Apr 23 '18 at 13:24
  • I agree with @Newbee. Your posting helped me too. – Jim T Jan 12 '19 at 17:35
15

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
Billy Bob Bain
  • 2,894
  • 18
  • 13
  • 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 Oct 01 '09 at 16:14
  • What does an strace log show? strace -o foobar.log java Test – Billy Bob Bain Oct 01 '09 at 17:16
3

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
  • 8,968
  • 3
  • 34
  • 47
3

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
  • 23,614
  • 16
  • 68
  • 106
  • 2
    My user not in /etc/passwd. Same for my colleague on his machine, though, but it works there. – digitalbreed Oct 01 '09 at 12:01
  • @AngeloNeuschitzer this thread is 2.5 years old and I no longer work for the company where I was having this issue, but no, I did not, since I had no root permissions for the system. Note that there's also a 2.5 years old solution for this issue as well ;) – digitalbreed Apr 13 '12 at 15:11
1

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
  • 23,614
  • 16
  • 68
  • 106
  • Just a note for anyone else that runs into this, Java is doing something more sophisticated than just appending the user name to "/home/". Home directories on my Linux network machines are located in "/nethome" – Ogre Psalm33 Feb 03 '14 at 15:00
  • ... and I guess - Java reports `/nethome/b` to be the respective home dir? – Grzegorz Oledzki Feb 03 '14 at 18:02
  • I do not have the respective permissions to perform all of the operations in the 2nd block on our project's servers, but I would have to presume so, given that the java bug database entry (linked in other answers/comments) indicates Java can fall back to LDAP, depending on system configuration. – Ogre Psalm33 Feb 03 '14 at 22:40
1

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
  • 5,400
  • 3
  • 19
  • 35
1

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!
Ogre Psalm33
  • 21,366
  • 16
  • 74
  • 92
  • Props to @PascalThivent who provided the link earlier that turned me on to this possibility. – Ogre Psalm33 Feb 03 '14 at 16:30
  • This should be more generic. Check `/etc/nsswitch.conf`, and get the full list of providers used for `passwd` service. Then make sure that all corresponding `/lib/libnss_xxx` libraries are installed for 32bit as well. I ran into the same problem with `sss` provider. Can be tricky to find the right package as well sometimes. – Pawel Veselov Mar 12 '15 at 23:16
1

I had the same problem, and inspired on @digitalbreed's answer I've discovered a similar, but different solution. In my case everything was 64 bit. However, I noticed that the problem was only when running from command line, while if I tried it from IntelliJ, it worked fine - because it used a different JDK.

Thus, I've removed the JDK I was using from CLI (openjdk-15.0.1-ga, supplied by nix-env), and added IntelliJ's JDK (openjdk-16.0.1) to PATH, and now it's fine.

Zvika
  • 1,542
  • 2
  • 17
  • 21
1

I had this problem when running the mvn docker image, which is running java in the background and shares this problem. I think this answer had the right diagnosis, but the solution didn't work for me. I had to mount a local .m2 folder in two places to get the folder to cache properly. It wanted to use the /root/.m2 for some things and /scratch/?/.m2 for other things, so I mounted them both

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
Mech
  • 11
  • 1
0

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.