2011-01-28 7 views
7

Tôi đang làm việc trên một trình cắm thêm Eclipse cần các lớp không biết lúc biên dịch. Các lớp được gửi qua mạng trong các tệp jar. Tôi muốn tải động các lớp đó trong thời gian chạy.Thêm các lọ vào một trình cắm thêm Eclipse tại thời gian chạy

Tôi đã thử phương pháp được liệt kê tại đây: http://blog.imaginea.com/making-applications-work-together-in-eclipse/

Rất tiếc, nó không có hiệu quả mong muốn. Trong khi các lớp được tải, tôi không thể sử dụng chúng bên ngoài hàm mà tôi đã nạp chúng. Tôi đoán nó có liên quan đến việc sử dụng các trình nạp lớp khác nhau.

Mọi trợ giúp đều được đánh giá cao. Ngay cả khi bạn nói với tôi, rằng nó là không thể, vì vậy tôi biết tôi không cần phải tìm thêm bất kỳ.

Trả lời

5

Nếu bạn thực hiện những lọ vào bó OSGi (ví dụ, cung cấp cho họ một MANIFEST.MF) sau đó bạn có thể cài đặt chúng vào thời gian chạy OSGi động.

Nếu bạn thêm một bó activator để plugin của bạn, sau đó bạn có thể lưu trữ các org.osgi.framework.BundleContext và sau đó bạn có thể làm:

Bundle [] newBundle = new Bundle[] { bundleContext.install(location, newJarInputStream) }; 
    packageAdmin.refreshPackages(newBundle); 
    packageAdmin.resolveBundles(newBundle); 

packageAdmin là một thể hiện của org.osgi.service. packageAdmin.PackageAdmin là một dịch vụ mà bạn có thể có được với BundleContext#getService

Các lọ mới có thể là toàn bộ gói theo cách riêng của chúng hoặc chúng cũng có thể là các gói có plugin của bạn làm máy chủ lưu trữ. Nếu chúng là các mảnh của gói của bạn thì gói của bạn (BundleContext#getBundle()) sẽ cần phải được bao gồm trong mảng được truyền tới refreshPackages và resolveBundles.

(Chỉnh sửa lớp tải) Class.forName từ mã plugin của bạn sẽ chỉ tìm các lớp trong gói mới được cài đặt nếu plugin của bạn có các gói phụ thuộc vào gói mới khi chúng được giải quyết.

  • Một cách để thực hiện việc này sẽ là tùy chọn Import-Package trong tệp kê khai của plugin của bạn. Trong trường hợp này, plugin của bạn sẽ cần được bao gồm trong mảng được chuyển đến refreshPackages.
  • Một tùy chọn khác là sử dụng câu lệnh DynamicImport-Package trong tệp kê khai của plugin của bạn. Nhập động được giải quyết trong khi tải lớp học

Tùy chọn khác là sử dụng Bundle.loadClass (thay vì Class.forName) trên đối tượng bó cho gói mới được cài đặt của bạn. Điều này sử dụng trình nạp lớp của gói mới để bản thân plugin của bạn không cần phải có sự phụ thuộc vào các gói mới.

+0

Điều này nghe có vẻ đúng cách để làm điều đó (+1) –

+0

Cảm ơn bạn. Nghe có vẻ như một cách tiếp cận tốt. Tôi vẫn còn có một số rắc rối, mặc dù. Tôi đã quản lý để tải gói. Nhưng Class.forName ("MyClass") vẫn ném ngoại lệ ClassNotFound. Tôi đã chỉ định gói chứa lớp trong câu lệnh xuất của tệp kê khai – Maria

+0

Tôi đã chỉnh sửa câu trả lời gốc với nhiều chi tiết hơn về tải lớp khi các gói được cài đặt. –

1

Gần đây tôi đã làm điều này cho một plugin để che khuất:

Dưới đây là mã nổi bật

URL[] urls = new URL[]{ new URL("jar", "", "file:" + jarFile.getAbsolutePath() + "!/")}; 
URLClassLoader cl = URLClassLoader.newInstance(urls, this.getClass().getClassLoader()); 
Class<?> loadedClass = cl.loadClass("com.whatever.SomeClass");