NoClassDefFoundError on a protocol when requiring its namespace
This is the recipe for the exception I'm getting (EDIT: ProtoImpl
is defined in an开发者_JS百科other ns, I'll leave it out to ease the description):
myns.clj
(ns myns)
(defprotocol Proto
(func [this]))
(extend-protocol Proto
ProtoImpl
(func [this] (do-something ...)))
interop.clj
(ns interop
(:require [myns :as m]))
(defn startup
[]
(m/func (ProtoImpl.)))
(gen-class :name interop.Interop
:prefix "interop-"
:methods [[boot [] void]])
(defn interop-boot
[this]
(startup)))
Both myns.clj and interop.clj are shipped within a webapp, the latter being also AOT compiled thus produging Interop.class available in the classpath right away. This is instantiated as a Spring bean.
When the webapp starts, it fails to bootstrap with the following exception:
[...]
at myns__init.load(Unknown Source)
at myns__init.<clinit>(Unknown Source)
[...]
at interop.Interop.<clinit>(Unknown Source)
[...]
Caused by: NoClassDefFoundError: myns.Proto
What can cause this issue?
EDIT: I cannot reproduce the error anymore, I recompiled and re-run the application, which started up flawlessly... Still I would really like to understand in which situations such an issue can show up.
It looks to me like the class loader couldn't find the class definition for Proto
, which I assume is the role of clojure RT to load as soon as the relevant .clj source file is parsed. As you can see in the extract of the stack trace I receive, myns is being loaded, and it it exactly there that Proto
is defined. How come I got a NoClassDefFoundError
?
Clojure Records are supposed to be imported. The following should work:
(ns interop
(:require [myns :as m])
(:import myns.Proto))
I was having the same problem. Adding both classes to :aot
in my project.clj
resolved the issue. Your project.clj
would have something like this: :aot [myns interop]
.
精彩评论