I am developing an application in clojure using compojure, ring-json, and using lein-ring to test while developing (using the "lein ring server" command) and to package the app into a war file to deploy on Tomcat 7.0.42. I have a page that uses jQuery to do an ajax post request to a url that responds data from an updated database record. While developing, running under the "lein ring server" command, the javascript works perfectly. It collects the inputs, sends the post data, and the server responds with the data I'm looking for.
When I package up the app and deploy it in the "webapps" directory of Tomcat, my app runs correctly, let's me log in, pulls data from the database, and handles form post requests correctly (the login, for example, sends the data via the login form to the server and everything works). But when I navigate to the page with the javascript ajax request, however, I get the following error:
SEVERE: Servlet.service() for servlet [performancecenter.routes/app servlet] in context with path [/performance] threw exception
java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:312)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.read(Unknown Source)
at clojure.core$slurp.doInvoke(core.clj:6279)
at clojure.lang.RestFn.invoke(RestFn.java:410)
at ring.middleware.json$read_json.doInvoke(json.clj:12)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at ring.middleware.json$wrap_json_body$fn__3427.invoke(json.clj:19)
at ring.middleware.json$wrap_json_params$fn__3431.invoke(json.clj:31)
at ring.middleware.json$wrap_json_response$fn__3438.invoke(json.clj:42)
at performancecenter.servlet$_service$fn__706.invoke(servlet.clj:1)
at ring.util.servlet$make_service_method$fn__50.invoke(servlet.clj:126)
at performancecenter.servlet$_service.invoke(servlet.clj:1)
at performancecenter.servlet.service(Unknown Source)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Here is the compojure routes function for the post request url and the app function that wraps the requests with the ring-json functions:
(defroutes page-routes
(POST "/log/performance/api" {session :session params :params}
(enter-production-record (:user session) params)))
(def app
(-> (routes login-routes main-routes)
(auth/with-user)
(handler/site :session)
(middleware/wrap-json-body)
(middleware/wrap-json-params)
(middleware/wrap-json-response)))
And here is the function that returns the json data (and which works in development):
(defn enter-production-record [user params]
(let [m (data/insert-producer-metric (:id user))
r (data/get-productivity m)]
{:body {:productivity (float (:productivity_factor r))}}))
I admittedly know very little about Tomcat, but reading around I found examples of this error and it usually was related to a function in the application closing a stream early or something. I don't understand exactly what's going on here, or how my function would be doing that. Any help would be appreciated, thanks!