使用Clojure中的静态方法生成类

时间:2014-04-08 16:12:56

标签: java clojure interop

我有一个Clojure库,我想在Java中使用,但是我无法获得正确的类生成。我想生成一个有效的类:

public class TokenStore {
    public static TokenStore Sns(Map<String, String> services) { /* ... */ }

    public String addToken(String token, String username, String service) { /* ... */ }
    public String findToken(String username, String service) { /* ... */ }
    public String sendNotification(String username, String service, String message) { /* ... */ }
}

以下是我在Clojure中要做的事情:

(ns my.lib.token-java
  (:require [my.lib.token :refer :all])
  (:gen-class
   :name my.lib.TokenStore
   :methods [#^{:static true} [Sns [java.util.Map] TokenStore]]))

(defprotocol TokenStore
  (addToken [this token username service])
  (findToken [this username service])
  (sendNotification [this username service message]))

(defn -Sns [services]
  (let [ts (token-store (apply concat (for [[k v] (into {} coll)] [(keyword k) v]))]
    (reify TokenStore
      (addToken [this token username service]
        (add-token this token username service))
      (findToken [this username service]
        (find-token this username service))
      (sendNotification [this username service message]
        (send-notification this username service message)))))

但是当我尝试编译它时,我得到:

: jmglov@alhana; lein jar
Compiling orron-iii.push-java
Exception in thread "main" java.lang.ClassNotFoundException: java.lang.TokenStore, compiling:(orron_iii/push_java.clj:1:1)

有人能给我一个如何做到的简单例子吗?

1 个答案:

答案 0 :(得分:2)

这不是我问题的直接答案,但它可能是实现我想要的更好方式。这有点像“博士,当我这样做时会很痛。” “然后停止这样做!”那类的东西。 :)

我使用标准gen-class foo来创建一个扩展java.lang.Object的类,并整齐地包装我的Clojure令牌存储内容(如纯Clojure my.lib.token文件中所定义)。

(ns my.lib.token-java
  (:require [my.lib.token :as t])
  (:gen-class
   :name my.lib.TokenStore
   :constructors {[java.util.List] []}
   :init initialise
   :state localstate
   :methods [[addToken [String String String] String]
             [findToken [String String] String]
             [sendNotification [String String String] String]]))

(defn- keywordise [coll]
  (flatten (map (fn [[k v]] [(keyword k) v]) (partition 2 coll))))

(defn -initialise [services]
  (let [token-store (apply t/sns-token-store (keywordise services))]
    [[] (ref token-store)]))

(defn -addToken [this service username token]
  (t/add-token @(.localstate this) (keyword service) username token))

(defn -findToken [this service username]
  (t/find-token @(.localstate this) (keyword service) username))

(defn -sendNotification [this service username message]
  (p/send-notification @(.localstate this) (keyword service) username message))

我现在可以像这样在Java中使用它:

import my.lib.TokenStore;
import java.util.Arrays;

public class TokenTool {
    public static void main(String[] args) {
        TokenStore tokenStore = new TokenStore(Arrays.asList("APNS", "arn:aws:sns:..."));

        String deviceId = tokenStore.findDevice("APNS", "foo");
        System.out.println("Device is: " + deviceId);

        tokenStore.sendNotification("APNS", "foo", "Test for echo");
    }
}

这看起来效果很好。