web-dev-qa-db-ja.com

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環境変数をすでに確認しました。

24
digitalbreed

少し恥ずかしいですが、解決策は単に64ビットシステムで64ビットJDKを使用することでした。私は古いマシンからすべてをコピーしましたが、これは32ビットJDKも意味し、これが問題でした。 64ビットランタイムで期待どおりに動作しました。

おじゃまします。

31
digitalbreed

解決策ではなく回避策。 -Duser.home=$HOMEを引数として追加することで、それを設定できるはずです。

Java -Duser.home=$HOME Test
8
Billy Bob Bain

他の保証された特性についてはどうですか?次のようなものを呼び出すとどうなりますか?


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

3
CPerkins

wdsは彼/彼女のコメントで正しいです。 user.home値は/ etc/passwdから取得されたようです。ユーザーの/etc/passwdの行は何ですか?

エントリを/home/nonexistingに変更した場合、Testクラスは/home/nonexistingを出力しました。/etc/passwdに?がありますか?

2

何が起こっているのかを正確に把握するために、ネイティブコードを確認する必要があります。 user.home変数は、Linuxシステムの「PAM」モジュールによって設定されます。使用中のモジュールがこれらを動的に生成し、Java実装が明示的にPAMを使用せずに値を取得しようとすると、動作は予測できないため、「?」

1
whatnick

完全を期すために、問題のシステムが(/ etc/passwdではなく)LDAP認証を使用するように構成されている場合も、このバグレポートで概説されている問題が問題である可能性があります。 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!
1
Ogre Psalm33

面白いですね。 user.homeプロパティが$ HOME環境変数から取得されていないようです。私はこれを試しました:

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

/home/grzole

シェルは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ディレクトリがないのでしょうか。

1

私も同じ問題を抱えていました。上記のように、32ビットのJavaには、32ビットのldapライブラリもインストールする必要があります。そうでない場合、説明されたエラーが発生します。

Libnss_ldap.so.2および依存パッケージをインストールすると、問題が解決します。

0
Steffen Kux