34

私はこれで完全に迷っています: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 環境変数を確認しました。

4

10 に答える 10

39

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

おじゃまします。

于 2009-10-02T09:39:53.287 に答える
14

回避策であり、解決策ではありません。-Duser.home=$HOME引数として追加することで設定できるはずです。

java -Duser.home=$HOME Test
于 2009-10-01T11:37:38.203 に答える
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's current working directory");
    }
    public static void printAProperty (String propName, String desc) {
       System.out.println ("Value for '" + desc + "' is '" + System.getProperty(propName) + "'.");
    }

于 2009-10-01T11:41:51.050 に答える
3

wds は彼/彼女のコメントで正しいです。値はuser.home/etc/passwd から取得されているようです。/etc/passwdあなたのユーザーにとってあなたのラインは何ですか?

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

于 2009-10-01T11:48:47.757 に答える
1

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

于 2009-10-01T13:35:43.767 に答える
1

それは本当に興味深いです。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ファイルシステムにディレクトリがまったくない可能性がありますか?

于 2009-10-01T11:19:32.933 に答える
1

完全を期すために、問題のシステムが (/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!
于 2014-02-03T16:28:13.510 に答える
0

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

libnss_ldap.so.2 とそれに依存するパッケージをインストールすると、問題が解決します。

于 2014-10-10T06:19:51.137 に答える