อัปเดต : เนื่องจากคำตอบนี้ถูกโพสต์เครื่องมือบางอย่างที่มีการเปลี่ยนแปลง หลังจากคำตอบดั้งเดิมมีการอัปเดตรวมถึงข้อมูลเกี่ยวกับวิธีสร้างตัวอย่างด้วยเครื่องมือปัจจุบัน
มันไม่ง่ายเหมือนการคอมไพล์ไปที่ jar และเรียกเมธอดภายใน ดูเหมือนจะมีกลเม็ดเล็กน้อยที่จะทำให้ทุกอย่างทำงานได้ นี่คือตัวอย่างของไฟล์ Clojure ง่ายๆที่สามารถคอมไพล์ลงใน 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)))
)
หากคุณเรียกใช้คุณควรเห็นสิ่งต่อไปนี้:
(binomial 5 3): 10
(binomial 10042 111): 49068389575068144946633777...
และนี่คือโปรแกรม Java ที่เรียกฟังก์ชั่นใน-binomial
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));
}
}
มันเป็นผลผลิต:
(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263
ชิ้นแรกของเวทมนต์ใช้:methods
คำสำคัญในgen-class
คำสั่ง ที่ดูเหมือนว่าจะต้องให้คุณเข้าถึงฟังก์ชั่น Clojure เช่นวิธีการคงที่ใน Java
สิ่งที่สองคือการสร้างฟังก์ชั่น wrapper ที่สามารถเรียกได้โดย Java โปรดสังเกตว่ารุ่นที่สอง-binomial
มีเส้นประอยู่ด้านหน้า
และแน่นอนขวด Clojure นั้นจะต้องอยู่ในเส้นทางของชั้นเรียน ตัวอย่างนี้ใช้ jar Clojure-1.1.0
อัปเดต : คำตอบนี้ได้รับการทดสอบอีกครั้งโดยใช้เครื่องมือต่อไปนี้:
- Clojure 1.5.1
- Leiningen 2.1.3
- JDK 1.7.0 อัพเดท 25
ส่วน Clojure
ขั้นแรกสร้างโครงการและโครงสร้างไดเรกทอรีที่เกี่ยวข้องโดยใช้ Leiningen:
C:\projects>lein new com.domain.tiny
ตอนนี้เปลี่ยนเป็นไดเรกทอรีโครงการ
C:\projects>cd com.domain.tiny
ในไดเรกทอรีโครงการให้เปิดproject.clj
ไฟล์และแก้ไขตามที่แสดงด้านล่าง
(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)
ตอนนี้ตรวจสอบให้แน่ใจว่าการอ้างอิงทั้งหมด (Clojure) พร้อมใช้งาน
C:\projects\com.domain.tiny>lein deps
คุณอาจเห็นข้อความเกี่ยวกับการดาวน์โหลดโถ Clojure ณ จุดนี้
ตอนนี้แก้ไขไฟล์ Clojure C:\projects\com.domain.tiny\src\com\domain\tiny.clj
เพื่อให้มีโปรแกรม Clojure ที่แสดงในคำตอบเดิม (ไฟล์นี้สร้างขึ้นเมื่อ Leiningen สร้างโครงการ)
เวทมนตร์ส่วนใหญ่ที่นี่อยู่ในการประกาศเนมสเปซ ระบบ:gen-class
บอกให้สร้างคลาสที่com.domain.tiny
มีชื่อด้วยวิธีการคงที่เดียวที่เรียกว่าbinomial
ฟังก์ชั่นรับอาร์กิวเมนต์จำนวนเต็มสองข้อและส่งกลับสองครั้ง มีสองฟังก์ชันที่มีชื่อคล้ายกันคือฟังก์ชันbinomial
Clojure แบบดั้งเดิมและ-binomial
และ wrapper สามารถเข้าถึงได้จาก Java -binomial
หมายเหตุยัติภังค์ในชื่อของฟังก์ชั่น คำนำหน้าเริ่มต้นคือเครื่องหมายขีดกลาง แต่สามารถเปลี่ยนเป็นอย่างอื่นได้หากต้องการ -main
ฟังก์ชั่นเพียงแค่ทำให้คู่ของการโทรไปยังฟังก์ชั่นทวินามเพื่อให้มั่นใจว่าเราจะได้รับผลลัพธ์ที่ถูกต้อง เมื่อต้องการทำเช่นนั้นให้คอมไพล์คลาสและเรียกใช้โปรแกรม
C:\projects\com.domain.tiny>lein run
คุณควรเห็นผลลัพธ์ที่แสดงในคำตอบเดิม
ตอนนี้บรรจุไว้ในขวดและวางไว้ที่ใดที่หนึ่งที่สะดวก คัดลอกโถ Clojure ที่นั่นด้วย
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.
ส่วนของ Java
Leiningen มีงานในตัวlein-javac
ซึ่งน่าจะสามารถช่วยในการคอมไพล์ Java น่าเสียดายที่ดูเหมือนว่าจะใช้งานไม่ได้ในเวอร์ชัน 2.1.3 ไม่พบ JDK ที่ติดตั้งและไม่พบที่เก็บ Maven เส้นทางที่ทั้งสองมีช่องว่างที่ฝังตัวในระบบของฉัน ฉันคิดว่านั่นเป็นปัญหา Java IDE ใด ๆ ก็สามารถจัดการกับการคอมไพล์และแพ็คเกจได้เช่นกัน แต่สำหรับโพสต์นี้เรากำลังจะไปโรงเรียนเก่าและทำมันที่บรรทัดคำสั่ง
ขั้นแรกให้สร้างไฟล์Main.java
พร้อมเนื้อหาที่แสดงในคำตอบดั้งเดิม
เพื่อรวบรวมส่วน java
javac -g -cp target\com.domain.tiny-0.1.0-SNAPSHOT.jar -d target\src\com\domain\Main.java
ตอนนี้สร้างไฟล์ที่มีข้อมูล meta เพื่อเพิ่มลงใน jar ที่เราต้องการสร้าง ในManifest.txt
เพิ่มข้อความต่อไปนี้
Class-Path: lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar
Main-Class: Main
ตอนนี้บรรจุมันทั้งหมดลงในไฟล์ jar ขนาดใหญ่หนึ่งไฟล์รวมถึงโปรแกรม Clojure และ jar 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
ในการรันโปรแกรม:
C:\projects\com.domain.tiny\target>java -jar Interop.jar
(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263
เอาท์พุทจะเหมือนกับที่ผลิตโดย Clojure เพียงอย่างเดียว แต่ผลลัพธ์ที่ได้จะถูกแปลงเป็น Java double
ตามที่กล่าวไว้แล้ว Java IDE อาจดูแลข้อโต้แย้งการรวบรวมและบรรจุภัณฑ์ที่ยุ่งเหยิง