2012-08-27 52 views
5

我在Tomcat上運行現有的Java Web應用程序重新加載Clojure的代碼到我加入一些原始的Clojure支持。目前,我只是將Clojure源文件作爲資源包含在classpath中,並通過clojure.lang.RT調用它。這是原始的,但工作正常。在Tomcat中

但是,我注意到Tomcat的WebappClassLoader緩存通過getResourceAsInputStream()檢索到的資源,Clojure用它來檢索和編譯源代碼。也就是說,儘管(require 'my-ns :reload)只是更新了文件的緩存版本,但即使磁盤上有更新的版本。有沒有辦法規避或避免Clojure文件的緩存?

最好的我已經拿出了很多沒結果的谷歌搜索後使用反射手動刪除WebappClassLoader.resourceEntries這是可怕的條目。

我必須缺少一些東西。

答案,如「使用碼頭/ Glassfish的/ JBoss的」,「重新啓動Tomcat」等是不是我要找的。

回答

2

你不會要能夠規避WebappClassLoader的行爲存在。你可以做的是移動在其管轄範圍之外加載的代碼;例如至$CATALINA_HOME/lib,如here所述。

你需要將所有的依賴有作爲,讓你實際部署的web應用程序作爲期望所有的代碼已經在其他地方提供一個小的shell .war文件。

這將讓你出去WebappClassLoader的管轄權,並希望其語義爲好。 (如果它緩存從父類加載器加載的東西,那看起來會徹底破壞IMO。)

+0

謝謝Chas。我必須考慮一下。把東西放在'lib'中並不方便。我想知道'* use-context-classloader *'會不會影響其他內容。 –

+0

@DaveRay'* use-context-classloader *'默認爲true。將其設置爲false會導致加載路徑通過加載Clojure本身的ClassLoader - 如果將Clojure從webapp加載或者導致破壞(即將clojure.jar放入$ CATALINA_HOME/lib中) '但嘗試從webapp加載代碼)。 問:爲什麼不從Web應用程序啓動REPL服務器,連接到它,並以這種方式加載代碼? – cemerick

+0

謝謝。也許我只是沒有足夠的創造力,我會如何使用REPL服務器:)說我有一堆代碼在磁盤上的幾個文件。我啓動了運行repl服務器的Tomcat,如何在那裏獲取所有代碼? –

0

你可以把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類爲我工作。

+0

看來,如果我可以通過'clojure.lang.RT'以這種方式加載文件就可以工作。否則,'(require'foo:reload)'將繼續使用上下文類加載器。 –

0

描述here這是關係到cachingAllowed標誌?剛射入藍色。

0

或者使用Clojure中的補丁版本,做了沿線:

(io/input-stream (io/resource "bla.clj")) 

我發現了一個句話上,這是不緩存淨。

+0

'(io/resource)'使用上下文類加載器,所以它將通過Tomcat並被緩存。 :( –

+0

@ dave-ray我發現'.getResource'(被'io/resource'使用)沒有被緩存,我不知道Tomcat,在我這邊,這是所有的猜測。 – kotarak