2012-02-25 36 views
13

Tôi đang cố gắng tạo ứng dụng khách/máy chủ RMI Java. Tôi đang gặp sự cố khi khởi động phía máy chủ của ứng dụng, vì nó tiếp tục chạy vào một ClassNotFoundException trong khi gọi đến phương thức Registry.bind() khi tôi cố gắng khởi động phía máy chủ của ứng dụng.Làm cách nào để đặt classpath mà rmiregistry sử dụng?

Tôi bắt đầu với hướng dẫn đơn giản tại đây: http://docs.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hello-world.html. Sau khi làm theo các hướng dẫn đó, ban đầu nó đã ném một ClassNotFoundException phàn nàn rằng nó không thể tìm thấy "example.hello.Hello". Tôi đã có thể giải quyết điều đó bằng cách bắt đầu quá trình rmiregistry từ thư mục destDir trong hướng dẫn, vì rõ ràng là, sử dụng thư mục khởi đầu ban đầu của nó như là một phần của classpath của nó.

Tôi bắt đầu trên ứng dụng thử nghiệm khác của mình sau đó và tôi đã ổn cho đến khi tôi bắt đầu sử dụng các tệp jar của bên thứ ba trong lớp máy chủ của tôi. Bây giờ Registry.bind() ném ClassNotFoundException nếu lớp máy chủ của tôi tham chiếu bất cứ thứ gì trong bất kỳ tệp jar nào kể từ khi ứng dụng rmiregistry không biết về các tệp jar đó.

Theo như tôi có thể nói, rmiregistry không chấp nhận bất kỳ loại classpath khởi động arg, vì vậy tôi tự hỏi làm thế nào tôi có thể nói cho nó những gì classpath tôi muốn nó thừa nhận. Theo hướng dẫn tại đây: http://docs.oracle.com/javase/tutorial/rmi/running.html, "bạn phải đảm bảo rằng vỏ hoặc cửa sổ mà bạn sẽ chạy rmiregistry hoặc có no biến môi trường CLASSPATH hoặc có biến môi trường CLASSPATH không bao gồm đường dẫn đến bất kỳ lớp nào mà bạn muốn tải xuống cho khách hàng của các đối tượng ở xa của bạn. " Nghe có vẻ như trái ngược với những gì tôi cần ... hoặc tôi đọc nó không chính xác? Có ai có thành công trong việc khởi động máy khách/máy chủ RMI sử dụng các lọ bên thứ ba (commons-io, commons-logging, và rmiio, trong trường hợp của tôi) không?

Đây là trên Windows, theo cách của họ.


Cập nhật Tôi tìm thấy một con đường xung quanh nó. Xem câu trả lời của tôi dưới đây.

+3

Làm việc tốt. Như một lời nhắc thân thiện, bạn có thể tự mình đăng câu trả lời cho câu hỏi và sau đó chấp nhận câu trả lời đó để chúng tôi có thể đóng câu hỏi này không? Ngoài ra, bạn cần chấp nhận câu trả lời cho các câu hỏi trước nếu chúng khắc phục được sự cố của bạn. – Zecas

Trả lời

3

(Ban đầu tôi đã gửi câu trả lời này là một cập nhật cho câu hỏi của tôi. Đề nghị của mỗi Zecas tại một trong những ý kiến, tôi di chuyển nó đến phần đáp án.)

tôi đã có thể để có được những phần máy chủ để bắt đầu lên bởi không tuân theo sự gợi ý trong hướng dẫn thứ hai tham chiếu trong câu hỏi của tôi trên:

"bạn phải chắc chắn rằng vỏ hoặc cửa sổ mà bạn sẽ chạy rmiregistry hoặc có không biến môi trường CLASSPATH đặt hoặc có biến môi trường CLASSPATH không bao gồm đường dẫn đến bất kỳ lớp nào bạn muốn tải xuống cho khách hàng của các đối tượng từ xa . "

Tôi đã tạo biến môi trường CLASSPATH và thêm thư mục đầu ra .class và mỗi tệp jar của bên thứ ba vào đó. Tôi nghĩ rằng tôi đã thử điều đó trước đây, nhưng tôi đoán là không ... Chỉ nghĩ rằng tôi sẽ để lại giải pháp của tôi trong trường hợp người khác có cùng một vấn đề.

+0

CLASSPATH cũng phải được đặt trong máy khách? Đang nhận ClassNotFoundException: . _stub –

4

Không có đường dẫn lớp Java cụ thể của RMI Registry. Nó nên sử dụng cùng một classpath như phần còn lại của hệ thống Java. Bạn có thể thiết lập classpath của bạn bằng cách chỉ định nó trên dòng lệnh, hoặc trong môi trường hệ điều hành của bạn. Mặc dù một ít ngày, điều này doc nên chỉ cho bạn đi đúng hướng.

1

Một ví dụ về làm thế nào để thiết lập classpath cho rmiregistry

Win32:

set CLASSPATH=c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar 

UNIX:

setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar 
+0

Nhận xét về việc không đặt CLASSPATH chỉ áp dụng nếu bạn đang sử dụng tính năng codebase. Câu hỏi đặt ra là làm thế nào để * thiết lập * nó, không phải là làm thế nào để bỏ đặt nó, và không ai hỏi về việc thay đổi cổng. Bạn sẽ đăng câu trả lời này bao nhiêu lần nữa ở những nơi không liên quan hôm nay? – EJP

+0

bạn có thể xem làm thế nào để thiết lập classpath trong câu trả lời của tôi, nhưng tôi nghĩ rằng mục tiêu của bạn là chỉ để downvote câu trả lời của tôi, không phải để đọc chúng một cách cẩn thận !!! – MCHAppy

+0

Mục tiêu của tôi là đảm bảo rằng các câu hỏi được trả lời một cách phù hợp và chính xác. Phần mà bây giờ bạn tham chiếu không có mặt khi tôi nhận xét và 95% câu trả lời khác của bạn vẫn không liên quan. – EJP

5

Các nhận xét về unset classpath chỉ áp dụng nếu bạn đang sử dụng RMI tính năng codebase, vì nhận xét khó hiểu về việc tải xuống các lớp học nhằm mục đích ngụ ý.

Nếu bạn không sử dụng các tính năng codebase, chỉ cần một trong hai:

  1. Đặt biến môi trường CLASSPATH theo yêu cầu trước khi bắt đầu rmiregistry, như ở những nơi khác ở đây, hoặc
  2. Bắt đầu rmiregistry với -J-Djava.class.path=...
  3. Bắt đầu Registry bên trong JVM máy chủ của bạn, với LocateRegistry.createRegistry(). Đây là giải pháp tốt nhất theo nhiều cách, vì nó tồn tại và chết với JVM, chia sẻ classpath của nó, và tình cờ tuân thủ các yêu cầu đối với tính năng codebase.

Nếu bạn thực hiện (3), bạn phải lưu giá trị trả về vào biến tĩnh để ngăn không cho nó bị thu gom rác, điều này làm cho sổ đăng ký không được báo cáo. điều này có thể dẫn đến GCX, điều này sẽ dẫn đến việc thoát khỏi chuỗi lắng nghe, điều này có thể dẫn đến toàn bộ quá trình thoát JVM.

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