Serving static files from a war

243 views
Skip to first unread message

Siddhartha Reddy

unread,
Dec 8, 2009, 1:33:12 AM12/8/09
to comp...@googlegroups.com
I've been able to deploy my compojure app as a war inside Tomcat by following the instructions on this list and elsewhere. But I've now run into another problem: the serve-file handler no longer serves the static files (gives a 404). This is quite understandable since serve-file is looking for the files in './public'. I'm unable to figure out how to work around this. Please help.

Thanks,
Siddhartha

Kosta Sokolov

unread,
Dec 8, 2009, 2:00:59 AM12/8/09
to comp...@googlegroups.com
as far as I remember you can provide a path for serve-file

(GET "/*"
(or (serve-file "YOUR-PATH" (params :*)) :next))

Regards,
Kosta

2009/12/8 Siddhartha Reddy <sids....@gmail.com>:
> --
>
> You received this message because you are subscribed to the Google Groups
> "Compojure" group.
> To post to this group, send email to comp...@googlegroups.com.
> To unsubscribe from this group, send email to
> compojure+...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/compojure?hl=en.
>

Siddhartha Reddy

unread,
Dec 8, 2009, 3:09:09 AM12/8/09
to comp...@googlegroups.com
Thank you, Kosta. The problem is, I'm not sure what path to pass to serve-file. I could store the static files at the root of the war and then pass ServletContext.getRealPath("/") but that is not guaranteed to work across servlet containers if the app is deployed as a war file instead of as a war directory. Moreover, it does not work in my development environment where I run the app using Jetty.

Best,
Siddhartha

Shantanu Kumar

unread,
Dec 8, 2009, 3:17:39 AM12/8/09
to comp...@googlegroups.com
On Tue, Dec 8, 2009 at 1:39 PM, Siddhartha Reddy <sids....@gmail.com> wrote:
Thank you, Kosta. The problem is, I'm not sure what path to pass to serve-file. I could store the static files at the root of the war and then pass ServletContext.getRealPath("/") but that is not guaranteed to work across servlet containers if the app is deployed as a war file instead of as a war directory. Moreover, it does not work in my development environment where I run the app using Jetty.

When in a WAR, you can either load files through the class loader (see link below) or let the web container handle them on its own (through a different servlet path).


In the example at the URL below, I have used the second option.


Regards,
Shantanu

Siddhartha Reddy

unread,
Dec 8, 2009, 4:58:04 AM12/8/09
to comp...@googlegroups.com
Thanks, Shantanu.

I've successfully used the first option you have suggested. But I'm curious about the second option. From your build.xml, I notice that you include all your static files at the root of your war. Now I'm not sure how you configure a different servlet path in your web container to serve only these files. Can you please provide some sample config that would accomplish this? Thanks.

In case anyone else is interested, here is the helper I used to serve up static files using ClassLoader.getResourceAsStream():

(defn serve-public-resource [path]
  (.getResourceAsStream (clojure.lang.RT/baseLoader) (str "public/" path)))

This can be used the same way as serve-file. I've configured ant to copy the public/ directory (that contains all my static files) to WEB-INF/classes/ in the war; the container will ensure that WEB-INF/classes/ is on the classpath.

Best,
Siddhartha

--

Shantanu Kumar

unread,
Dec 8, 2009, 5:30:00 AM12/8/09
to comp...@googlegroups.com
On Tue, Dec 8, 2009 at 3:28 PM, Siddhartha Reddy <sids....@gmail.com> wrote:
Thanks, Shantanu.

I've successfully used the first option you have suggested. But I'm curious about the second option. From your build.xml, I notice that you include all your static files at the root of your war. Now I'm not sure how you configure a different servlet path in your web container to serve only these files. Can you please provide some sample config that would accomplish this? Thanks.


There is this notion of development-environment versus production-environment that I follow. For production environment, the web.xml file is picked up from conf/web.xml (look for the "war" target in build.xml) -- all compojure routes go to /blog/* whereas the other static files are automatically picked up from classpath by the container. For development environment, I serve static files (see /src/blogjure/mvc/blog_servlet.clj), which is sort of hack'ish, but gets the job done.

For information to those who may not be aware of the typical setup, static files can be served more efficiently by Apache (HTTPD) and the dynamic resources can be served by the servlet container (Tomcat, JBoss, whatever). This makes option #2 (described above) suited to better-manageable deployment configuration.

Regards,
Shantanu
Reply all
Reply to author
Forward
0 new messages