Reputation: 40005
I have an existing Java webapp running in Tomcat to which I'm adding some primitive Clojure support. For the time being, I'm just including Clojure source files as resources on the classpath and invoking it through clojure.lang.RT
. It's primitive, but works fine.
However, I've noticed that Tomcat's WebappClassLoader
caches resources retrieved through getResourceAsInputStream()
which Clojure uses to retrieve and compile source code. That is, doing (require 'my-ns :reload)
just reloads the cached version of the file even though an updated one is available on disk. Is there a way to circumvent or avoid this caching for Clojure files?
The best I've come up with after much fruitless googling is to use reflection to manually remove the entry from WebappClassLoader.resourceEntries
which is awful.
I must be missing something.
Answers like "use Jetty/Glassfish/JBoss", "restart Tomcat", etc aren't what I'm looking for.
Upvotes: 5
Views: 649
Reputation: 17299
Or use a patched version of clojure which does something along the lines:
(io/input-stream (io/resource "bla.clj"))
I found a remark on the net that this is not cached.
Upvotes: 0
Reputation: 17299
Is this related to the cachingAllowed
flag as described here? Just shooting into the blue.
Upvotes: 0
Reputation: 1240
Can you put the Clojure source files under WEB-INF
? Then you can read them using http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getResourceAsStream(java.lang.String)
servletContext.getResourceAsStream("/WEB-INF/foo/core.clj");
This worked for me in the past to load un-cached Groovy classes from source in Tomcat.
Upvotes: 0
Reputation: 5916
You're not going to be able to circumvent WebappClassLoader
's behaviour there. What you can do is move the code that's being loaded outside of its jurisdiction; e.g. up to $CATALINA_HOME/lib
, as described here.
You'll need to move all of your dependencies there as well, leaving the .war file you actually deploy as a webapp as a small shell that expects all the code to already be available elsewhere.
This will get you out of WebappClassLoader
's jurisdiction, and hopefully its semantics as well. (If it caches things loaded from parent classloaders, that would seem thoroughly broken IMO.)
Upvotes: 2