2012-03-18 27 views
6

Tôi đang làm việc trên dự án nguồn mở. Tính đến bây giờ tôi không có bất kỳ tùy biến trong bất kỳ lớp học. Vì vậy, sử dụng tất cả các tệp tin jars được cung cấp bởi dự án mã nguồn mở. Câu hỏi của tôi là nếu tôi sửa đổi một tệp java, biên dịch nó và đóng gói tệp jar mới với cấu trúc thư mục giống nhau, sẽ có vấn đề gì khi khởi động máy chủ hoặc thời gian chạy không? Nếu không phải tập tin lớp nào sẽ được gọi (tệp mặc định hoặc tệp lớp java tùy chỉnh của tôi)?Tệp lớp java nào sẽ được gọi nếu cùng một lớp được đóng gói trong hai tệp jar?

+0

Tôi tin rằng JVM sẽ sử dụng lớp này từ tệp jar đầu tiên mà nó có thể tìm thấy trong đường dẫn lớp. Và một câu hỏi tương tự đã được trả lời ngày hôm nay chính nó "Cách JVM hoạt động khi hai cùng một jar được bao gồm trong classpath" – sachinrahulsourav

+0

có thể trùng lặp của [Làm thế nào JVM hoạt động khi hai cùng một jar được bao gồm trong classpath] (http://stackoverflow.com/ câu hỏi/9757279/how-jvm-works-khi-hai-cùng-jar-be-bao gồm-trong-classpath) –

Trả lời

10

Trong thực tế nó phụ thuộc vào nhiều yếu tố:

  • Nếu cả hai tập tin jar đang trong ClassLoader cùng, ví dụ classpath Java (-cp tùy chọn), thông thường nó sẽ là file đầu tiên được tìm thấy trong jar danh sách đơn đặt hàng.

  • Nếu được triển khai trong vùng chứa JavaEE, như trong tệp EAR hoặc trong WEB-INF/lib hoặc tệp WAR, sẽ không có bảo hành nào chứa cùng lớp giữa hai lần khởi động. Trong bối cảnh đó, điều duy nhất chắc chắn là WEB-INF/classes được tìm kiếm trước khi WEB-INF/lib

  • Trong một hệ thống phân cấp ClassLoader phức tạp, hành vi mặc định là tìm kiếm cha mẹ đầu tiên nhưng JavaEE triển khai đã giới thiệu các cơ chế như chính sách giữa phụ huynh và cuối cùng (WebSphere) hoặc lọc nhờ vào deployment descriptor (WebLogic)

Một lựa chọn có thể tuyên bố jar file dependencies trong META-INF/MANIFEST.MF tập tin nhờ vào thuộc tính Class-Path. Nó sẽ thực thi một thứ tự tải ở mức ClassLoader, đặc biệt khi bắt đầu với java -jar myapp.jar nhưng nó có thể phụ thuộc vào việc triển khai trong ngữ cảnh JavaEE.

Lưu ý: khi sử dụng dự án OpenSource, có thể công bằng khi gửi yêu cầu thay đổi và xuất bản các thay đổi hoặc cải tiến của bạn để cộng đồng hưởng lợi từ nó. Sau đó dự án của bạn có thể cập nhật lên luồng chính mà không gặp khó khăn về các bản vá lỗi hoang dã trong ClassPath của bạn.

+0

Như bạn đã nói Nếu cả hai tệp jar nằm trong cùng một ClassLoader, ví dụ như đường dẫn lớp Java (tùy chọn -cp), thông thường nó sẽ là tệp đầu tiên được tìm thấy trong thứ tự danh sách jar. Nhưng một lần nữa ở điểm thứ hai, bạn nói nếu nó là trường hợp với tập tin chiến tranh triển khai trong webcontainer như tomcat, mà lớp tập tin sẽ được gọi là không được bảo đảm. Đúng không? –

+0

Một điểm nữa. Bạn đã nói Một tùy chọn có thể là khai báo phụ thuộc tệp jar trong tệp META-INF/MANIFEST.MF nhờ thuộc tính Class-Path. Nó sẽ thực thi một thứ tự tải ở mức ClassLoader nhưng nó có thể phụ thuộc vào việc triển khai thực hiện trong một ngữ cảnh JavaEE. Chỉ cần xác nhận rằng sự hiểu biết của tôi nếu lớp A được đóng gói trong hai tệp jar J1 và J2. Lớp A được gọi từ lớp B (được đóng gói trong J3) .Nếu chúng ta muốn Class A từ jar J2 được gọi, thì chúng ta cần đề cập đến điều này trong tệp menifest của jar J3. Chính xác? –

+0

Có chính xác. Tệp kê khai J3 phải chứa Class-Path: j2.jar và tệp kê khai J2 phải chứa Class-Path: j1.jar. Vì vậy, nó thực thi thứ tự tải đầu tiên: j3, sau đó j2, sau đó j1. Đặc biệt hữu ích khi được đóng gói với thuộc tính Main-Class. –

1

Trình tải lớp đang tìm kiếm địa điểm đầu tiên cần có tài nguyên cần thiết. Điều đó có nghĩa là nếu lớp học có cùng tên và gói xuất hiện trong 2 lọ, cái đầu tiên được tìm thấy sẽ được sử dụng. Cái nào là cái đầu tiên? Theo classpath: nếu ví dụ hạng A xuất hiện trong lọ one.jar và two.jar và dòng lệnh của bạn là:

java -cp one.jar;two.jar MyMain`

phiên bản từ one.jar sẽ được sử dụng. Nhưng nếu dòng lệnh là

java -cp two.jar;one.jar MyMain`

lớp từ two.jar sẽ được khởi tạo.

+4

Bạn có một tham chiếu nói rằng đây là * quy định/tài liệu * hành vi? Tôi [không nhìn thấy một] (http://stackoverflow.com/questions/9757279/how-jvm-works-when-two-same-jar-be-included-in-classpath/9757720#9757720). –

+0

điều gì xảy ra khi nó là 'java -cp/src/lib/* MyMain' và thư mục lib chứa one.jar và two.jar? – enator

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