2010-12-14 37 views
5

Chúng tôi có một số ứng dụng sử dụng Apache HTTPClient 3 để thực hiện các yêu cầu HTTP. Gần đây chúng tôi cũng đã bắt đầu tạo các máy khách dịch vụ web sử dụng HTTPClient 4 vì nhiều lý do khác nhau. Lập trường Apache là "các bản phát hành chính không tương thích ngược". Trong khi tôi muốn cập nhật tất cả các dự án của chúng tôi để sử dụng phiên bản 4, điều đó đơn giản là không khả thi.Truy cập nhiều phiên bản của gói trong Java

Vì vậy, trong khi câu hỏi chính của tôi là khá chung chung, thì câu hỏi cụ thể của tôi là. Tôi có thể sử dụng HTTPClient phiên bản 3 và 4 trong cùng một ứng dụng như thế nào? Trong trường hợp của chúng tôi, một ứng dụng có thể là một trang web, máy tính để bàn hoặc ứng dụng dòng lệnh.

Tôi đã đọc số SO question for java-dynamically-load-multiple-versions-of-same-class dường như bán gần nhưng tôi không quan tâm quá nhiều đến phần động. Trong thực tế, tôi muốn các JAR được vận chuyển với ứng dụng (ví dụ, WEB-INF/lib cho các ứng dụng web) Tôi cũng thấy một số câu hỏi tương tự như câu hỏi này nhưng dường như quá mức hoặc có lẽ quá phức tạp (có thể một ví dụ đơn giản có thể chứng minh bằng cách khác).

Cuối cùng tôi muốn để có thể trao một nhóm tập hợp các lọ rằng họ có thể thả vào và nó chỉ hoạt động độc lập với dự án của họ sử dụng HTTP khách hàng 3.

+1

Đây là trường hợp quản trị kiến ​​trúc là một ý tưởng hay: quyết định gắn bó với phiên bản 3 hoặc chuyển mọi thứ sang phiên bản 4. Bây giờ bạn phải trả chi phí triển khai cho giải pháp chắp vá và sẽ chỉ trở nên tồi tệ hơn theo thời gian. – Anon

+1

@Anon: Không có hành vi phạm tội nhưng không biết tình hình tôi sẽ không tư vấn làm như một tuyên bố chăn. Tôi đã nói "vì nhiều lý do" để tránh những nhận xét như vậy. –

+0

OSGi ít nhất là công trình (Bạn cần phải quyết định nếu nó quá mức cần thiết hay không), tôi không biết cách nào khác để làm điều này ngoài việc có hai máy chủ web, một cho mỗi phiên bản của thư viện. –

Trả lời

5

Như những người khác đã nêu, bạn có thể tạo nhiều trình nạp lớp và tải hai phiên bản một cách riêng biệt. Phần này là dễ dàng đủ.

Vấn đề là, điều này về cơ bản sẽ chia tách "không gian lớp học" của bạn và sẽ rất khó để chỉ v3 từ một số phần trong ứng dụng của bạn trong khi đề cập đến v4 từ các phần khác trong ứng dụng của bạn. Bạn sẽ phải phân vùng ứng dụng của bạn rất một cách cẩn thận ... vậy tại sao không chỉ chia nhỏ ứng dụng và phân phối hai ứng dụng?

OSGi có thể là một giải pháp nếu bạn có thể tính toán chức năng thành dịch vụ.Nhưng việc chuyển đổi một ứng dụng kế thừa sang OSGi không phải là một cái gì đó để tiếp nhận một cách nhẹ nhàng, và nó chắc chắn sẽ không phải là một lối thoát rẻ từ cái bẫy mà bạn đã bước vào. Tôi nói điều này là tác giả của một cuốn sách về OSGi và một nhà truyền giáo nổi tiếng về OSGi. Mục tiêu dài hạn của việc chuyển đổi các ứng dụng của bạn sang OSGi sẽ mang lại cho bạn những lợi ích tuyệt vời, nhưng cũng sẽ bao gồm chi phí đáng kể lên phía trước.

1

Sử dụng bộ tải nhiều lớp, một cho mỗi Ứng dụng khách HTTP mà bạn muốn nắm bắt.

Cách đơn giản nhất là mở rộng URLClassLoader và hack nó để mã hóa đường dẫn lớp cho từng phiên bản riêng biệt. Sau đó, bạn chỉ cần đảm bảo phần còn lại của mã biết phiên bản nào của ứng dụng khách HTTP sử dụng (và truy cập trình nạp lớp chính xác để truy cập vào nó).

+0

Làm thế nào điều này sẽ làm việc cho một ứng dụng web, nơi các JAR phải vận chuyển với các WAR? –

+0

Bạn gửi tất cả các phiên bản của từng thư viện được tham chiếu, nhưng đặt chúng ở đâu đó khác với web-inf/lib. Trình tải lớp tùy chỉnh của bạn trông ở vị trí "ở một nơi khác". Điều này ngăn cản các container chiến tranh trực tiếp tham khảo chúng. –

1

Bạn phải sử dụng trình nạp lớp riêng cho v3 và v4. Đặt v3 và v4 lọ để tách các thư mục ngoài đường dẫn ứng dụng của bạn. Sử dụng URLClassLoadedr để tải từng phiên bản. URL mà bạn chuyển đến từng trình tải lớp nên chứa URL cho phiên bản ứng dụng HTTP cụ thể.

Nhưng tôi có thể cho bạn lời khuyên không? Kiểm tra trước rằng bạn thực sự cần tất cả những điều này trước khi bạn bắt đầu. Điều đó đúng là các phiên bản có thể không tương thích. Nhưng có một cơ hội rất lớn mà họ đang có.

+1

Tôi nghĩ rằng bạn có nghĩa là "cơ hội lớn họ là * không *" Tôi biết HTTP Client v3 và V4 không chơi tốt với nhau. –

2

Một giải pháp dễ dàng nhưng đơn giản sẽ là bạn sẽ có được nguồn cho HttpClient3 và HttpClient4, và cấu trúc lại tên gói cái gì đó như

org.apache.commons.httpclient3 cho HttpClient3 và org.apache.commons .httpclient4 cho HttpClient4 để tránh va chạm. Sau đó biên dịch, gói, xong.

Giờ đây, thật dễ dàng chuyển đổi giữa hai lần triển khai và chúng không xung đột trong trình nạp lớp.

+1

Trong khi điều này làm việc cho một cái bình, nó tạo ra nhiều vấn đề hơn là giải quyết. Ví dụ, bạn có thể cần apache.commons.logging và cả hai phiên bản sẽ phụ thuộc vào các phiên bản khác nhau của việc ghi nhật ký commons (vì chúng được phát hành vào các thời điểm khác nhau). Bây giờ bạn có thể repack commons đăng nhập theo cách trên, nhưng sau đó bạn phải quay trở lại và tự chỉnh sửa tất cả mã nguồn trong các máy khách http được đóng gói lại để tham chiếu chính xác. Chẳng bao lâu một giải pháp trở thành một mớ hỗn độn lớn. –

+1

Chúng có thực sự phụ thuộc vào các phiên bản ghi nhật ký khác nhau không? Cái mới nhất sẽ hoạt động tốt với cả hai, phải không? – Thilo

+2

Lưu ý rằng người dân commons-lang đang đi tuyến đường này. Commons Lang 3 sẽ sử dụng tên gói org.apache.commons.lang3. Nếu bạn sẽ có những thay đổi API không tương thích, một tên gói mới có lẽ không phải là ý tưởng tồi tệ nhất. – Thilo

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