I have a problem where I am trying to do an isa? or instance? check on an object of a record type which is defined in an AOT-compiled namespace. The isa? check fails because -- under circumstances which I do not yet well understand -- the object I actually have is an instance of its class in a clojure.lang.DynamicClassLoader, whereas a reference to the class by its literal name yields the class in the base sun.misc.Launcher$AppClassLoader.
My Clojure code is compiled into a jar which is included into a Jetty server whose app code is largely written in Java. Here is an example which illustrates the problem: ;; src/foo/core.clj (ns foo.core) (defrecord T [a b]) ;; project.clj (defproject foo "1.0.0-SNAPSHOT" :dependencies [[org.clojure/clojure "1.4.0"]] :aot [foo.core]) Now if I add the artifact foo/foo as a Maven dependency of the Jetty server, and attach a liverepl to the running server (without taking any action to call the Clojure code from Java), I see the following: Clojure 1.4.0 user=> (require '[foo.core]) nil user=> (.getClassLoader foo.core.T) #<AppClassLoader sun.misc.Launcher$AppClassLoader@a6eb38a> user=> (.getClassLoader (type (foo.core.T. 1 2))) #<AppClassLoader sun.misc.Launcher$AppClassLoader@a6eb38a> user=> (.getClassLoader (type (foo.core/->T 1 2))) #<DynamicClassLoader clojure.lang.DynamicClassLoader@433d3253> My actual case is more complicated, but the principle is the same: instances of foo.core.T which were built by the defrecord constructor function ->T do not inhabit the AppClassLoader version of the class, but rather a DynamicClassLoader version. The result is that instance? or instanceof checks -- whether in my own Clojure code or in that of Java clients of my library who are trying to downcast -- do not behave as expected. This example cannot be reduced too far: if one just builds an uberjar and invokes a repl on the Clojure library alone, using 'java -cp target/foo-1.0.0-SNAPSHOT-standalone.jar clojure.main', the result is different: Clojure 1.4.0 user=> (require '[foo.core]) nil user=> (.getClassLoader foo.core.T) #<AppClassLoader sun.misc.Launcher$AppClassLoader@43be2d65> user=> (.getClassLoader (type (foo.core.T. 1 2))) #<AppClassLoader sun.misc.Launcher$AppClassLoader@43be2d65> user=> (.getClassLoader (type (foo.core/->T 1 2))) #<AppClassLoader sun.misc.Launcher$AppClassLoader@43be2d65> Unfortunately I don't understand enough about the Clojure class loading mechanism to understand what might be causing the DynamicClassLoader to be invoked in one case and not the other. This problem seems to have been described by Ryan Senior about 20 months ago on clojure-dev, but I do not find any follow-up posts: https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/VBJFMEFBeFY Can anyone shed light on the situation? thanks, Chris Jeris -- Chris Jeris cje...@brightcove.com (617) 686-3271 freenode/twitter/github: ystael -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en