compojure/ring unable to slurp static file when compressed under .war

230 views
Skip to first unread message

Thao

unread,
Apr 14, 2014, 1:30:12 AM4/14/14
to comp...@googlegroups.com
I need to pack this Compojure/Ring little application to .war file to deploy with Tomcat/Elastic Beanstalk. It works fine with lein/jetty locally, but under tomcat it gives me this: 
HTTP Status 500 - resources/public/login.html (No such file or directory)
type Exception report
message resources/public/login.html (No such file or directory)
description The server encountered an internal error that prevented it from fulfilling this request.
exception
java.io.FileNotFoundException: resources/public/login.html (No such file or directory)
java.io.FileInputStream.open(Native Method


 the project structure:

├── project.clj
├── README.md
├── repo
│   └── local
├── resources
│   └── public
│       └── login.html
├── src
│   └── framework
│       ├── handler.clj
│       ├── session
│       │   └── session.clj
│       └── view
│           └── injectJson.clj
├── target
│   └── framework.war
└── test
    └── framework
        └── test
            └── handler.clj


project.clj:

(defproject framework "0.1.0-SNAPSHOT"
  :repositories {"local" "file:repo"}
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [compojure "1.1.6"]]
  :plugins [[lein-ring "0.8.10"]]
  :ring {:handler framework.handler/app}
  :profiles
  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                        [ring-mock "0.1.5"]]}}
    :resource-path "resources/")

handle.clj:

(ns ...)

(defroutes app-routes
(GET "/" [] 
(view/inject (ses/newSid) "login.html"))

(route/resources "/")
(route/not-found "Not Found lalala"))

(def app
(wrap-cookies (handler/site app-routes)))

injectJson.clj (basically put the json object into the html file's header, cuz another person's filling out the page and making them learn clojure is abit much)

(ns...))

(defn inject [json file2Returned]
(let [ file (str "resources/public/" file2Returned)
content (slurp file)
where (+ 6 (.indexOf content "<head>"))
newContent (str (.substring content 0 where) json 
(.substring content where))]
newContent))


When I do lein ring uberwar, it gives this .war file with no static resources in it, and won't work even if I put it in manually. What did I do wrong here? 
Thanks.

James Reeves

unread,
Apr 14, 2014, 5:32:37 AM4/14/14
to Compojure
Resources are files that are included on the classpath, much like source files. Trying to access them like files isn't a robust solution, as they could potentially be packaged up (in your case, within a war or uberwar).

Instead, use the clojure.java.io/resource function:

    (slurp (io/resource (str "public/" file-to-return)))

This generates a URL to your resource that you can use with "slurp".

You can also remove the ":resource-path" option from your project.clj file. Leiningen will by default look for resources in the "resources" directory, and then add them to the class path.

- James


--
You received this message because you are subscribed to the Google Groups "Compojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to compojure+...@googlegroups.com.
To post to this group, send email to comp...@googlegroups.com.
Visit this group at http://groups.google.com/group/compojure.
For more options, visit https://groups.google.com/d/optout.

Thao

unread,
Apr 14, 2014, 11:46:19 AM4/14/14
to comp...@googlegroups.com, ja...@booleanknot.com
Hi James, thanks for the reply, but tomcat stil gives me HTTP Status 500 - resources/public/login.html (No such file or directory), altho it's fine under lein/jetty. When packaged into .war file it still doesn't include the resources folder. I'm running lein 2.3.4/java7/mint. My code:

injectJson.clj:
(defn inject [json file-to-return]
(let [ content (slurp (io/resource (str "public/" file-to-return)))
where (+ 6 (.indexOf content "<head>"))
newContent (str (.substring content 0 where) json 
(.substring content where))]
newContent))

project.clj (remove resource path)

(defproject framework "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [compojure "1.1.6"]]
  :plugins [[lein-ring "0.8.10"]]
  :ring {:handler framework.handler/app}
  :profiles
  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                        [ring-mock "0.1.5"]]}})

James Reeves

unread,
Apr 14, 2014, 11:54:18 AM4/14/14
to Compojure
How are you packaging the war file? I'm unable to reproduce your issue:

lein ring war
Created /Users/jim/Development/thao/target/thao-0.1.0-SNAPSHOT.war
jar -tf target/thao-0.1.0-SNAPSHOT.war | grep public
WEB-INF/classes/public/login.html

What do you get when you run those commands?

Incidentally, are you trying to manually deploy the war, or are you using the lein-beanstalk plugin?

- James

Thao

unread,
Apr 14, 2014, 12:05:21 PM4/14/14
to comp...@googlegroups.com, ja...@booleanknot.com
I package it via lein ring uberwar. If i do lein ring war it doesn't even run under tomcat, and doesn't include dependent jar libraries. Right now I'm just throwing it in tomcat/webapps and run tomcat/bib/startup.sh.

Could you give an example of accessing static file without front-end framework(hiccup, enlive etc) and run it in tomcat7? 

James Reeves

unread,
Apr 14, 2014, 12:38:52 PM4/14/14
to Compojure
What do you get when you look inside the uberwar you created? Is there a file "WEB-INF/classes/public/login.html"?

What's the exact error message you're getting? Have you done a "lein clean" before "lein ring uberwar" to ensure that the error doesn't originate from an old class file?

- James
Message has been deleted

Thao

unread,
Apr 14, 2014, 2:17:18 PM4/14/14
to comp...@googlegroups.com, ja...@booleanknot.com
I've got it working now. Sorry for the trouble!!
and thanks alot. 
Reply all
Reply to author
Forward
0 new messages