2009-10-01 55 views
23

Tôi hoàn toàn bị mất trên trang này: System.getProperty("user.home")System.getProperty("user.name") trả về dấu chấm hỏi "?".Java: System.getProperty ("user.home") trả về "?"

System-Specs: 
Kubuntu 9.04 
Gnome 2.2.61 
Java 1.5.0_16 

testcase của tôi trông như thế:

$ more Test.java 
class Test { public static void main(String[] args) { System.out.println(System.getProperties()); } } 

Kết quả là (thêm dòng-chia để có thể đọc tốt hơn, thay thế tên công ty và tên riêng):

$ 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= 
} 

Có ai bao giờ kinh nghiệm đó? Java tìm kiếm ở đâu để tìm người dùng và thư mục chính? Tôi đã kiểm tra biến môi trường HOME được đặt chính xác.

+0

Hmmm. Chưa bao giờ thấy điều đó. Có 'echo $ HOME' hoạt động từ dòng lệnh không? Thử in 'System.getProperties()'? –

+0

Từ/etc/passwd có thể? Thư mục chính có động không? – wds

+0

Bạn có chắc chắn đây là việc thực hiện mặt trời? – zedoo

Trả lời

27

Hơi xấu hổ một chút nhưng giải pháp đơn giản là sử dụng JDK 64 bit trên hệ thống 64 bit. Tôi đã sao chép mọi thứ từ máy cũ của mình, điều này cũng có nghĩa là một JDK 32 bit, và đây là vấn đề. Nó hoạt động như mong đợi với thời gian chạy 64-bit.

Xin lỗi vì đã làm phiền.

+14

Đừng xin lỗi vì làm phiền. Đó là một lỗi thực sự trong jvm, và bài đăng này cũng đã giúp những người khác ở đây trên SO. – extraneon

+3

Đây là http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6972329 (không được xác nhận là lỗi JDK, có thể là sự cố hệ thống). –

+0

Chúng tôi đã có cùng một vấn đề trong một thời gian dài. Sau khi đọc báo cáo lỗi mà @PascalThivent đã tham chiếu, đó chính xác là trường hợp của chúng tôi. Vấn đề này không xảy ra trên tài khoản cục bộ nhưng nó chỉ xảy ra trên tài khoản LDAP. Và vấn đề là phiên bản 32 bit của libnss_ldap không được cài đặt trong hệ thống của chúng tôi. Sau khi chúng tôi cài đặt gói bit nss_pam_ldap 32 bit, mọi thứ hoạt động suôn sẻ. – akifusenet

1

Điều đó thực sự thú vị. Có vẻ như tài sản user.home không được lấy từ biến môi trường HOME $. Tôi đã thử điều này:

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

/home/grzole 

Lưu ý rằng vỏ quên giá trị biến HOME, nhưng Java thì không.

EDIT: Tôi nghi ngờ Java chỉ nhận tiền tố /home/ và thêm tên người dùng. Hãy xem xét điều này:

# adduser b 
... 
# rm -fr /home/b 
# su - b 
No directory, logging in with HOME=/ 
$ cd /tmp/jb 
$ java Test 
/home/b 

Có lẽ bạn không có thư mục /home trong hệ thống tập tin của bạn ở tất cả?

+0

Chỉ cần một lưu ý cho bất cứ ai khác mà chạy vào điều này, Java đang làm một cái gì đó tinh vi hơn chỉ cần gắn thêm tên người dùng vào "/ home /". Trang chủ thư mục trên máy Linux mạng của tôi được đặt trong "/ nethome" –

+0

... và tôi đoán - Java báo cáo '/ nethome/b' là thư mục nhà tương ứng? –

+0

Tôi không có quyền tương ứng để thực hiện tất cả các hoạt động trong khối thứ hai trên máy chủ của dự án, nhưng tôi phải giả sử như vậy, vì mục nhập cơ sở dữ liệu java lỗi (được liên kết trong các câu trả lời/nhận xét khác) cho biết Java có thể rơi trở lại LDAP, tùy thuộc vào cấu hình hệ thống. –

6

Giải pháp thay thế, không phải giải pháp. Bạn có thể thiết lập nó bằng cách thêm -Duser.home=$HOME làm đối số.

java -Duser.home=$HOME Test 
+0

Vâng, tôi cũng đã đi theo cách đó, đổi tên java gốc thành java_bin và tạo một kịch bản lệnh shell để thêm các thuộc tính này vào dòng lệnh java_bin. Tuy nhiên, tôi không muốn chấp nhận điều này như là giải pháp, bởi vì phải có một cách tốt hơn. – digitalbreed

+0

Hiển thị nhật ký strace là gì? strace -o foobar.log java Thử nghiệm –

3

Còn các tài sản được bảo đảm khác thì sao? Điều gì sẽ xảy ra nếu bạn thực hiện một cuộc gọi đến một cái gì đó như sau?


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

2

wds phù hợp với nhận xét của anh ấy/cô ấy. Giá trị user.home dường như được lấy từ/etc/passwd. Đường dây của bạn trong số /etc/passwd cho người dùng của bạn là gì?

Nếu tôi thay đổi mục nhập thành /home/nonexisting, lớp Test được in /home/nonexisting. Bạn có xảy ra ? trong/etc/passwd không?

+1

Người dùng của tôi không có trong/etc/passwd. Tuy nhiên, đối với đồng nghiệp của tôi trên máy của anh ấy, nhưng nó hoạt động ở đó. – digitalbreed

+0

@digitalbreed bạn đã thử thêm nó ở đó chưa? –

+0

@AngeloNeuschitzer chủ đề này là 2,5 năm tuổi và tôi không còn làm việc cho công ty mà tôi gặp vấn đề này, nhưng không, tôi đã không, vì tôi không có quyền root cho hệ thống. Lưu ý rằng cũng có một giải pháp 2,5 năm cho vấn đề này là tốt;) – digitalbreed

1

Cần phải xem qua mã gốc để tìm ra chính xác những gì đang xảy ra. Biến user.home được thiết lập bởi các mô-đun "PAM" trong các hệ thống Linux và nếu mô-đun được sử dụng tạo ra các động này và việc triển khai Java đang cố gắng lấy giá trị mà không sử dụng PAM một cách rõ ràng thì hành vi là không thể đoán trước do đó "?"

1

Để hoàn thành, nó cũng giống như, nếu hệ thống được đề cập được cấu hình để sử dụng xác thực LDAP (và không/etc/passwd), thì vấn đề được nêu trong báo cáo lỗi này có thể là vấn đề: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6972329.Đảm bảo rằng libnss_ldap.so thích hợp được cài đặt cho hệ thống của bạn (ví dụ: thư viện LDAP 32 bit để sử dụng với Java 32 bit). Một số lệnh có thể hữu ích để xác định điều này có thể là:

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

Đạo cụ cho @PascalThivent, người đã cung cấp liên kết trước đó đã biến tôi thành khả năng này. –

+0

Điều này nên chung chung hơn. Kiểm tra '/ etc/nsswitch.conf' và nhận danh sách đầy đủ các nhà cung cấp được sử dụng cho dịch vụ' passwd'. Sau đó, đảm bảo rằng tất cả thư viện '/ lib/libnss_xxx' tương ứng được cài đặt cho 32bit. Tôi đã gặp vấn đề tương tự với nhà cung cấp 'sss'. Có thể khó khăn để tìm đúng gói cũng như đôi khi. –

0

Tôi cũng gặp vấn đề tương tự. Như đã đề cập ở trên, vấn đề là, Java 32 bit cũng cần phải cài đặt các thư viện ldap 32 bit. Nếu không, lỗi được giải mã sẽ xảy ra.

Cài đặt libnss_ldap.so.2 và các gói tùy chỉnh giải quyết được sự cố.

Các vấn đề liên quan