为什么需要这么干?因为clojure可以调用java的类,但有时候这些java类需要你实现一个子类或者传递一个自定义的java对象作为参数,所以需要将clojure代码编译成java代码。
还记得之前提过的:gen-class么,在(ns...)中,使用(:gen-class),在(ns..)之外,应该用 (gen-class)
下面是一个例子, 文件MoveDailyAction.clj内容如下:
(ns kafka2hdfs.MoveDailyAction (:import [org.apache.hadoop.fs FileSystem Path] [java.io.IOException] [java.text DateFormat SimpleDateFormat] [java.util.Date])) (gen-class :name "kafka2hdfs.MoveDailyAction" :implements [org.apache.storm.hdfs.common.rotation.RotationAction] :state dest :init init :constructors {[String][]}) (defn -init [dest] [[] dest])
具体可以参考下面两篇文档:
http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/gen-class
http://kotka.de/blog/2010/02/gen-class_how_it_works_and_how_to_use_it.html
为了在lein项目中,运行lein repl时自动加载并编译该类,需要在project.clj中的:aot中添加, 注意core.clj依赖MoveDailyAction.class,所以需要将MoveDailyAction放在前面先编译
:aot [kafka2hdfs.MoveDailyAction kafka2hdfs.core]
在repl中运行下面的代码测试:
kafka2hdfs.core=> (def o (kafka2hdfs.MoveDailyAction. "ab")) #'kafka2hdfs.core/o kafka2hdfs.core=> (.dest o) "ab"
构造函数接受的参数,在后面可以读取出来。