使用实例时ClassNotFoundException?在Clojure的defrecord类型

时间:2014-10-15 13:22:08

标签: clojure plumatic-schema

我编写的函数只选择在特定schema中命名的地图键:

(ns foo.schema
  (:require [schema.core :as s]))

(defn select-schema
  "Given a schema and a map m, selects only the keys of m that are named in the schema."
  [m schema]
  (let [optional? #(instance? schema.core.OptionalKey %)
        wildcard? #(= s/Keyword %)]
    (if (some wildcard? (keys schema))
      m  ; the schema allows any keyword as a key, so just return the map
      (let [ks (->> schema keys (map #(if (optional? %) (:k %) %)))]
        (select-keys m ks)))))

这在我的单元测试中效果很好:

(testing "Required key and wildcard"
    (let [schema {:foo s/Str, s/Keyword s/Any}]
      (is (= {:foo "Yup", :bar 42, :baz true} (select-schema {:foo "Yup", :bar 42, :baz true} schema)))
      (is (= {:foo "Yup", :bar 42} (select-schema {:foo "Yup", :bar 42} schema)))
      (is (= {:foo "Yup"} (select-schema {:foo "Yup"} schema)))))

然而,当我在一个完全独立的项目中使用foo.schema/select-schema时(即我的foo项目中的lein install来构建一个jar并将其粘贴在我的~/.m2/repository中并将其命名为依赖项) ,我得到一个ClassNotFoundException

Exception in thread "main" java.lang.ExceptionInInitializerError, compiling:(insurrection/test/handler.clj:1:1)
    at clojure.lang.Compiler.load(Compiler.java:7142)
    ...
Caused by: java.lang.ExceptionInInitializerError
    at foo.schema__init.load(Unknown Source)
    at foo.schema__init.<clinit>(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    ...
Caused by: java.lang.ClassNotFoundException: schema.core.OptionalKey
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    ...

我查看了Prismatic Sc​​hema源代码,发现OptionalKey是一种defrecord类型。一个小的谷歌搜索显示defrecord生成一个Java类,有时需要在定义它的命名空间后导入,但尝试在包含foo.schema的项目中执行此操作并没有任何区别:它在单元测试中工作,但在使用foo作为依赖项的其他项目中不起作用。

1 个答案:

答案 0 :(得分:-1)

您导出schema.cores。如果这是您正在运行的确切代码,则应该使用#(instance? s/OptionalKey %)作为optional?函数。

更不用说schemaselect-schema中的局部变量(参数)。