我有一个在Tomcat中运行的现有Java Web应用程序,我正在添加一些原始的Clojure支持。目前,我只是将 Clojure 源文件作为资源包含在类路径中,并通过 clojure.lang.RT
调用它。它是原始的,但工作正常。
但是,我注意到Tomcat的WebappClassLoader
缓存通过Clojure用来检索和编译源代码的getResourceAsInputStream()
检索的资源。也就是说,执行(require 'my-ns :reload)
只是重新加载文件的缓存版本,即使磁盘上有更新的版本。有没有办法规避或避免对 Clojure 文件的这种缓存?
经过许多徒劳的谷歌搜索后,我想出的最好的方法是使用反射手动从WebappClassLoader.resourceEntries
中删除条目,这很糟糕。
我一定错过了什么。
诸如"使用Jetty/Glassfish/JBoss","restart Tomcat"等答案不是我想要的。
你将无法规避WebappClassLoader
的行为。 您可以做的是将加载的代码移出其管辖范围;例如,最多 $CATALINA_HOME/lib
,如此处所述。
您还需要将所有依赖项移动到那里,将实际部署为 Web 应用的 .war 文件保留为一个小 shell,该外壳期望所有代码已在其他地方可用。
这将使你脱离WebappClassLoader
的管辖范围,希望它的语义也是如此。 (如果它缓存从父类加载器加载的内容,那似乎完全破坏了 IMO。
你能把 Clojure 源文件放在WEB-INF
下吗?然后你可以使用 http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getResourceAsStream(java.lang.String( 读取它们
servletContext.getResourceAsStream("/WEB-INF/foo/core.clj");
这在过去对我有用,可以从 Tomcat 中的源代码加载未缓存的 Groovy 类。
这与此处描述的cachingAllowed
标志有关吗?只是射入蓝色。
或者使用修补版本的 clojure,它的作用如下:
(io/input-stream (io/resource "bla.clj"))
我在网上发现了一个评论,说这个没有缓存。