2011-11-05 28 views
5

(Tôi biết điều này liên quan đến How can I embed Clojure in an RCP application, nhưng chủ đề đó là cũ và cài đặt của tôi là hơi khác nhau)Clojure vấn đề classpath trong vòng một plugin Eclipse

Tôi đang sử dụng Eclipse 3.7.1 và ngày nay có đã cố gắng viết một ứng dụng Eclipse/RCP trong Clojure (càng nhiều càng tốt). Tôi đã thử tạo phiên bản nguồn của clojure.osgiCCW, đã thử dự án giới thiệu RCPClojure và một số thứ khác. Mỗi người trong số họ không làm việc (chủ yếu dường như "không thể sửa được" lỗi xây dựng/classpath, thiếu tài liệu cập nhật/phản hồi, xung đột phiên bản, v.v ...)

Các bước của riêng tôi mang lại cho tôi ít nhất 50% thành công :

  1. Tạo một dự án plugin mới gói các tập tin jar Clojure 1.3.0, thiết lập Plugin ID org.clojure.v1.3.0

  2. Tạo một dự án plugin mới org.cljtest42 sử dụng RCP Xin chào mẫu

    1. Thêm org.clojure Plugin phụ thuộc
    2. Thêm tính chất dự án CCW (để cho phép AOT biên dịch), bước này thêm /classes thư mục
    3. Sửa plugin.xml thêm /classes thư mục để thời gian chạy classpath, cũng thêm org.cljtest42 để gói xuất khẩu.
  3. Thêm hai tập tin Clojure đơn giản trong org.cljtest42 gói/namespace:

    TestClass.clj:

    (ns org.cljtest42.TestClass 
    (:gen-class)) 
    
    (defn -main [greet] (println greet)) 
    

    compile.clj

    (ns org.cljtest42.compile) 
    (dorun (map compile ['org.cljtest42.TestClass])) 
    
  4. Kích hoạt AOT biên soạn bằng cách chọn nút dự án và chọn Chạy> Ứng dụng Clojure (/classes thư mục bây giờ sẽ được phổ biến với các lớp học clojure biên dịch).

  5. Reference TestClass từ lớp Activator (ví dụ trong start() - cũng đã cố gắng trong Perspective.createInitialLayout())

Cho đến nay rất tốt. Tuy nhiên, cố gắng chạy dự án này như là một ứng dụng Eclipse luôn thất bại với điều này:

java.io.FileNotFoundException: Could not locate org/cljtest42/TestClass__init.class or org/cljtest42/TestClass.clj on classpath: 
at clojure.lang.RT.load(RT.java:430) 
at clojure.lang.RT.load(RT.java:398) 
at clojure.core$load$fn__4610.invoke(core.clj:5386) 
at clojure.core$load.doInvoke(core.clj:5385) 
at clojure.lang.RestFn.invoke(RestFn.java:408) 
at clojure.lang.Var.invoke(Var.java:401) 
at com.pspctclr.cljtest42.TestClass.<clinit>(Unknown Source) 

Sẽ thật tuyệt vời nếu ai đó hiểu biết hơn có thể chia sẻ một số gợi ý về cách khắc phục vấn đề này. Có thể là do các lớp được biên dịch AOT không thực sự kết thúc trong classpath (không chắc chắn tại sao ?,/classes được thêm một cách rõ ràng) hoặc plugin Clojure riêng biệt không thể truy cập chúng do cách Equinox/OSGI công trinh?

Cảm ơn!

Trả lời

1

Sự cố có vẻ như gói Clojure không thấy các lớp của gói của bạn, mặc dù bạn đã xuất chúng. Điều này là, bởi vì, trong OSGi (như bạn có thể biết), để cho một gói có thể thấy một lớp, gói của nó cần được nhập khẩu.

Nhưng còn các trường hợp, trong đó một gói cần phải tải một lớp từ một gói, đã gọi nó. Để cho tiện làm việc, Eclipse đã triển khai buddy policies, được thiết kế chính xác cho trường hợp này:

  1. bó Clojure của bạn cần có biểu hiện tiêu đề Eclipse-BuddyPolicy: [dependent|registered].
  2. Nếu bạn đã thêm Eclipse-BuddyPolicy: registered, bạn sẽ cần phải thêm tiêu đề manifest vào bó, trong đó sử dụng Clojure: Eclipse-RegisterBuddy: <clojure-bundle-name>

Disclaimer: Tôi không có bất kỳ kinh nghiệm với Clojure, nhưng tôi muốn lấy một shot tại đây.

+0

Tác phẩm này hoạt động. Dưới đây là một số ghi chú bổ sung. 1) Trong plugin thời gian chạy Clojure của bạn, bạn phải xuất tất cả các gói trong jar. 2) Bạn có lẽ nên sử dụng 'Eclipse-BuddyPolicy: registered' trong plugin runtime và sau đó là mục nhập' Eclipse-RegisterBudy' tương ứng trong plugin phụ thuộc. 3) Nếu plugin phụ thuộc của bạn được gọi bởi các plugin khác không trực tiếp phụ thuộc vào plugin thời gian chạy Clojure của bạn, thì plugin phụ thuộc của bạn phải xem xét lại phụ thuộc thời gian chạy Clojure. – Bill

+0

Đây có lẽ là giải pháp đủ tốt, nhưng cách thích hợp để làm điều này là cho Clojure AOT thực sự tiêm các hàng nhập cần thiết vào gói, do đó bạn không phải sử dụng các bạn bè Eclipse khi nó đi xung quanh đặc tả OSGi. Nhưng điều này sẽ yêu cầu Clojure AOT làm điều đúng. –

+0

Điều đó giả định rằng bạn sẵn sàng AOT mã clojure của bạn. – Bill

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