extend-protocol导致NoClassDefFoundError

时间:2014-09-11 11:40:06

标签: clojure

与我的previous question相关,但不同。

我尝试使用clj-time.core.DateTimeProtocol实施deftype。我使用此而不是defrecord作为类型签名冲突(请参阅other question)。

我有两个文件。第一个是实现,第二个是测试。如您所见,测试文件尚未执行require实施文件以外的任何操作。为代码转储道歉,但这是最小的工作版本:

date.clj:

(ns util.date
  (:require [clj-time.core :as clj-time])
  (:require [clj-time.core :refer [DateTimeProtocol]])
  (:gen-class))

(defprotocol IWeirdDate
  (as-date [this]))

(deftype WeirdDate [year month day]
  IWeirdDate
  (as-date [this] (clj-time/date-time year month day)))

(extend-protocol DateTimeProtocol
    WeirdDate
    (year [this] (clj-time/year (as-date this)))
    (month [this] (clj-time/month (as-date this)))
    (day [this] (clj-time/day (as-date this)))
    (day-of-week [this] (clj-time/day-of-week (as-date this)))
    (hour [this] (clj-time/hour (as-date this)))
    (minute [this] (clj-time/minute (as-date this)))
    (sec [this] (clj-time/sec (as-date this)))
    (second [this] (clj-time/second (as-date this)))
    (milli [this] (clj-time/milli (as-date this)))
    (after? [this that] (clj-time/after? (as-date this) that))
    (before? [this that] (clj-time/before? (as-date this) that)))

(defn weird-date [y m d] (WeirdDate. y m d))

(def x (WeirdDate. 1986 5 2))
(def y (clj-time/date-time 2014 5 2))

(prn "Loaded OK source" x y)

date_test.clj

(ns util.date-test
  (:require [clojure.test :refer :all]
            [util.date :refer [weird-date]])
  (:require [clj-time.core :as clj-time]))

(def x (weird-date 1986 5 2))
(def y (clj-time/date-time 2014 5 2))

(prn "Loaded OK in test" x y)

这与lein testlein checklein compile等等有关。

奇怪的是源文件似乎工作正常:

"Loaded OK source" #<WeirdDate util.date.WeirdDate@7e793d7a> #<DateTime 2014-05-02T00:00:00.000Z>
Exception in thread "main" java.lang.NoClassDefFoundError: clj_time/core/DateTimeProtocol

问题出在其他地方,例如,在ns date-test声明中。我没有在其他任何地方引用DateTimeProtocol

如果我注释掉整个extend-protocol,结果就是:

"Loaded OK source" #<WeirdDate util.date.WeirdDate@3f19c149> #<DateTime 2014-05-02T00:00:00.000Z>
"Loaded OK source" #<WeirdDate util.date.WeirdDate@5c797bc6> #<DateTime 2014-05-02T00:00:00.000Z>
"Loaded OK in test" #<WeirdDate util.date.WeirdDate@19c6a644> #<DateTime 2014-05-02T00:00:00.000Z>

因此,看起来简单地从一个命名空间引用此协议就会阻止另一个命名空间(甚至没有提及它)加载。

什么?

0 个答案:

没有答案