Cập nhật : Vì câu trả lời này đã được đăng, một số công cụ có sẵn đã thay đổi. Sau câu trả lời ban đầu, có một bản cập nhật bao gồm thông tin về cách xây dựng ví dụ với các công cụ hiện tại.
Nó không đơn giản như biên dịch vào một jar và gọi các phương thức bên trong. Dường như có một vài thủ thuật để làm cho tất cả hoạt động mặc dù. Dưới đây là ví dụ về tệp Clojure đơn giản có thể được biên dịch sang tệp jar:
(ns com.domain.tiny
(:gen-class
:name com.domain.tiny
:methods [#^{:static true} [binomial [int int] double]]))
(defn binomial
"Calculate the binomial coefficient."
[n k]
(let [a (inc n)]
(loop [b 1
c 1]
(if (> b k)
c
(recur (inc b) (* (/ (- a b) b) c))))))
(defn -binomial
"A Java-callable wrapper around the 'binomial' function."
[n k]
(binomial n k))
(defn -main []
(println (str "(binomial 5 3): " (binomial 5 3)))
(println (str "(binomial 10042 111): " (binomial 10042 111)))
)
Nếu bạn chạy nó, bạn sẽ thấy một cái gì đó như:
(binomial 5 3): 10
(binomial 10042 111): 49068389575068144946633777...
Và đây là một chương trình Java gọi -binomial
hàm trong tiny.jar
.
import com.domain.tiny;
public class Main {
public static void main(String[] args) {
System.out.println("(binomial 5 3): " + tiny.binomial(5, 3));
System.out.println("(binomial 10042, 111): " + tiny.binomial(10042, 111));
}
}
Đầu ra của nó là:
(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263
Phần đầu tiên của phép thuật là sử dụng :methods
từ khóa trong gen-class
tuyên bố. Điều đó dường như được yêu cầu để cho phép bạn truy cập vào hàm Clojure giống như các phương thức tĩnh trong Java.
Điều thứ hai là tạo ra một hàm bao bọc có thể được gọi bởi Java. Lưu ý rằng phiên bản thứ hai của -binomial
có một dấu gạch ngang phía trước nó.
Và tất nhiên, chính chiếc bình Clojure phải nằm trên đường dẫn lớp. Ví dụ này đã sử dụng bình Clojure-1.1.0.
Cập nhật : Câu trả lời này đã được kiểm tra lại bằng các công cụ sau:
- Clojure 1.5.1
- Leiningen 2.1.3
- Cập nhật JDK 1.7.0 25
Phần Clojure
Đầu tiên tạo một dự án và cấu trúc thư mục liên quan bằng Leiningen:
C:\projects>lein new com.domain.tiny
Bây giờ, thay đổi thư mục dự án.
C:\projects>cd com.domain.tiny
Trong thư mục dự án, mở project.clj
tệp và chỉnh sửa sao cho nội dung được hiển thị bên dưới.
(defproject com.domain.tiny "0.1.0-SNAPSHOT"
:description "An example of stand alone Clojure-Java interop"
:url "http://clarkonium.net/2013/06/java-clojure-interop-an-update/"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.5.1"]]
:aot :all
:main com.domain.tiny)
Bây giờ, đảm bảo tất cả các phụ thuộc (Clojure) có sẵn.
C:\projects\com.domain.tiny>lein deps
Bạn có thể thấy một thông báo về việc tải xuống bình Clojure vào thời điểm này.
Bây giờ hãy chỉnh sửa tệp Clojure C:\projects\com.domain.tiny\src\com\domain\tiny.clj
sao cho nó chứa chương trình Clojure được hiển thị trong câu trả lời ban đầu. (Tệp này được tạo khi Leiningen tạo dự án.)
Phần lớn phép thuật ở đây là trong khai báo không gian tên. Nó báo :gen-class
cho hệ thống tạo một lớp có tên com.domain.tiny
với một phương thức tĩnh duy nhất được gọi binomial
, một hàm lấy hai đối số nguyên và trả về một số kép. Có hai hàm được đặt tên tương tự nhau binomial
, hàm Clojure truyền thống -binomial
và trình bao bọc có thể truy cập từ Java. Lưu ý dấu gạch nối trong tên hàm -binomial
. Tiền tố mặc định là một dấu gạch nối, nhưng nó có thể được thay đổi thành một cái khác nếu muốn. Các -main
chức năng chỉ làm một vài cuộc gọi đến các chức năng nhị thức để đảm bảo rằng chúng tôi đang nhận được kết quả chính xác. Để làm điều đó, biên dịch lớp và chạy chương trình.
C:\projects\com.domain.tiny>lein run
Bạn sẽ thấy đầu ra được hiển thị trong câu trả lời ban đầu.
Bây giờ gói nó trong một cái lọ và đặt nó ở đâu đó thuận tiện. Sao chép bình Clojure ở đó quá.
C:\projects\com.domain.tiny>lein jar
Created C:\projects\com.domain.tiny\target\com.domain.tiny-0.1.0-SNAPSHOT.jar
C:\projects\com.domain.tiny>mkdir \target\lib
C:\projects\com.domain.tiny>copy target\com.domain.tiny-0.1.0-SNAPSHOT.jar target\lib\
1 file(s) copied.
C:\projects\com.domain.tiny>copy "C:<path to clojure jar>\clojure-1.5.1.jar" target\lib\
1 file(s) copied.
Phần Java
Leiningen có một nhiệm vụ tích hợp sẵn, lein-javac
có thể giúp với việc biên dịch Java. Thật không may, nó dường như bị hỏng trong phiên bản 2.1.3. Nó không thể tìm thấy JDK đã cài đặt và nó không thể tìm thấy kho lưu trữ Maven. Các đường dẫn đến cả hai đều có không gian nhúng trên hệ thống của tôi. Tôi cho rằng đó là vấn đề. Bất kỳ IDE Java nào cũng có thể xử lý việc biên dịch và đóng gói. Nhưng đối với bài đăng này, chúng tôi sẽ đến trường cũ và thực hiện nó theo dòng lệnh.
Đầu tiên tạo tập tin Main.java
với nội dung hiển thị trong câu trả lời ban đầu.
Để biên dịch phần java
javac -g -cp target\com.domain.tiny-0.1.0-SNAPSHOT.jar -d target\src\com\domain\Main.java
Bây giờ hãy tạo một tệp có một số thông tin meta để thêm vào tệp mà chúng tôi muốn xây dựng. Trong Manifest.txt
, thêm văn bản sau
Class-Path: lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar
Main-Class: Main
Bây giờ gói tất cả vào một tệp jar lớn, bao gồm chương trình Clojure của chúng tôi và bình Clojure.
C:\projects\com.domain.tiny\target>jar cfm Interop.jar Manifest.txt Main.class lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar
Để chạy chương trình:
C:\projects\com.domain.tiny\target>java -jar Interop.jar
(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263
Đầu ra về cơ bản là giống hệt với sản phẩm do Clojure tạo ra, nhưng kết quả đã được chuyển đổi thành gấp đôi Java.
Như đã đề cập, một Java IDE có thể sẽ xử lý các đối số biên dịch lộn xộn và bao bì.