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

Reply via email to