I am setting up a web application building a route and handler with Ring and Compojure. Every time I try lein ring server I get a 404 Not Found. But I should see
Edit
After starting the server I am asked by IE to open or save the file. But Windows is not able to read the JSON file.
My project.clj looks like
(defproject web-viz
:dependencies [[org.clojure/clojure "1.4.0"]
[ring/ring-core "1.1.7"]
[ring/ring-jetty-adapter "1.1.7"]
[compojure "1.1.3"]
[hiccup "1.0.2"]]
:plugins [[lein-ring "0.8.3"]]
:ring {:handler web-viz.web/app})
and inside the src I have a file web.clj
(ns web-viz.web
(:require [compojure.route :as route]
[compojure.handler :as handler]
[clojure.string :as str])
(:use compojure.core
ring.adapter.jetty
[ring.middleware.content-type :only
(wrap-content-type)]
[ring.middleware.file :only (wrap-file)]
[ring.middleware.file-info :only
(wrap-file-info)]
[ring.middleware.stacktrace :only
(wrap-stacktrace)]
[ring.util.response :only (redirect)]))
(defroutes site-routes
(GET "/" [] (redirect "/data/census-race.json"))
(route/resources "/")
(route/not-found "Page not found"))
(def app (-> (handler/site site-routes)
(wrap-file "resources")
(wrap-file-info)
(wrap-content-type)))
There should be a file with the content above located at
web-viz/resources/public/data/census-race.json
You project is working for me. Here is how I structured the project
.
├── project.clj
├── resources
│ └── data
│ └── census-race.json
└── src
└── web_viz
└── web.clj
I don't see anything obviously wrong but the following looks unusual:
(def app (-> (handler/site site-routes)
(wrap-file "resources")
(wrap-file-info)
(wrap-content-type)))
From https://stackoverflow.com/a/22788463/894091:
You don't need any of the extra middleware like wrap-file,
wrap-file-info, or wrap-content-type, since compojure.route/resources
already does everything you need.
See if the following does the trick:
(def app
(handler/site app-routes))
Related
I am not able to get any response from the http-kit server when running using boot. It works with jetty. When I run the boot run the it exits after sometime. So I added (boot (wait)) which doesn't terminate, but the server seems to be not running.
; core.clj
(ns server.core
(:use [compojure.route :only [files not-found]]
[compojure.handler :only [site]]
[compojure.core :only [defroutes GET POST DELETE ANY context]]
org.httpkit.server))
(defn hello []
"Hello from httpkit")
(defroutes api-routes
(GET "/" [] (hello)))
(defn -main []
(run-server api-routes {:port 8080}))
The boot.clj file:
;boot.clj
(set-env!
:source-paths #{"src"}
:dependencies '[[org.clojure/clojure "1.8.0"]
[ring "1.5.0"]
[compojure "1.5.1"]
[http-kit "2.2.0"]])
(require '[server.core :as server])
(deftask run []
(with-pre-wrap fileset (server/-main) fileset)
(boot (wait)))
You can use boot-http and something like the following:
(boot (serve :handler 'server/-main :reload true) (wait))
I'm new to clojure and i'm having a hard time figuring out how to reload/ refresh the browser when changes have been made to either html/ js/ css etc.
this is my current setup project.clj
(defproject app2 "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://exampl.com/FIXME"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.9.89"]
[ring/ring-core "1.5.0"]
[ring/ring-jetty-adapter "1.5.0"]
[enfocus "2.0.0-SNAPSHOT"]]
:plugins [[lein-cljsbuild "1.1.3"]
[lein-ring "0.9.7"]]
:cljsbuild {:builds [{:source-paths ["src/cljs"],
:compiler {
:main "scripts.client"
:output-to "resources/public/js/main.js"
:output-dir "resources/public/js/out"
:asset-path "js/out"
;;:pretty-print true
;;:optimizations :none
}}]}
:main app2.server/app
:ring {:handler app2.server/app :auto-reload? true :auto-refresh? true :reload-paths ["src" "resources"]}
:profiles {
:dev {
:ring {
:nrepl {
:start? true
:port 9000
}
}
}
}
)
This is my server.clj
(ns app2.server
(:use [ring.middleware.resource :only [wrap-resource]]
[ring.middleware.file-info :only [wrap-file-info]]
[ring.middleware.reload :refer [wrap-reload]])
;;(:require app2.repl)
)
(defn handler
[request]
{:status 200}
)
;handling routing "/" -> "/index.html"
(defn wrap-index [handler]
(fn [req]
(println (pr-str req))
(if (= (:uri req) "/")
(handler (assoc req :uri "/index.html"))
(handler req))))
;setting up a simple resource handler for ring
(def app (-> handler
(wrap-resource "public")
(wrap-file-info)
(wrap-index)
(wrap-reload app {:dirs ["src" "resources"]})
))
How can this be accomplished?
I'm used to developing in node and you have tools like browser sync, weinre and supervisor. What are the equivalents in clojure?
I suggest you have a look at figwheel, which lets you do hot reloading of your ClojureScript and CSS in the browser.
There is of course not one good way of setting up your build, but my way to go for languages like SASS etc. is to watch and compile them as a separate process, and have Figwheel watch the generated CSS.
For example, on one of my ClojureScript projects, I had a script file for LESS compilation which used the LESS compiler and the wr utility directly:
#!/usr/bin/env bash
lessc src/styles/main.main.less resources/public/css/main.css --source-map && cp src/styles/*.less resources/public/css
wr "lessc src/styles/main.main.less resources/public/css/main.css --source-map && cp src/styles/*.less resources/public/css" src/**/*.less
Of course you can also use things like Gulp, Webpack - or any tool you're used to.
The alternative is to use Leiningen plugins, see the list here.
I'm building a Node.js app in ClojureScript and testing out macros.
Directory structure:
├── project.clj
└── src
└── lists
├── core.cljs
└── lib.clj
project.clj:
(defproject lists "0.1.0-SNAPSHOT"
:source-paths ["src/"]
:dependencies [[org.clojure/clojure "1.7.0"]]
:plugins [[lein-cljsbuild "1.1.2"]]
:cljsbuild {:builds
[{:source-paths ["src"]
:compiler {:output-to "target/lists.js"
:optimizations :simple
:target :nodejs}}]})
src/lists/core.cljs:
(ns lists.core
(:require [lists.lib :as lib :include-macros true]))
(enable-console-print!)
(lib/defmain [& args]
(console.log "hello world"))
src/lists/lib.clj:
(ns lists.lib)
(defmacro defmain [& body]
`(set! *main-cli-fn* (fn ~#body)))
When I run lein cljsbuild once, I get a huge error traceback containing:
Caused by: clojure.lang.ExceptionInfo: No such namespace: lists.lib, could not locate lists/lib.cljs or lists/lib.cljc at line 1 src/lists/core.cljs {:file "src/lists/core.cljs", :line 1, :column 1, :tag :cljs/analysis-error}
The folder structure is right, and :source-paths is present in both the outer
defproject call and inner :cljsbuild :builds object. What's even weirder is
that sometimes it exits without printing anything. Anyone have any ideas?
cljsbuild is throwing an exception because it doesn't understand .clj files, it's looking for .cljs or .cljc files in the "src" directory. You have to rename lib.clj to lib.cljc check using cljc on the clojurescript wiki.
I am new to clojure and liberator.
I am trying to get started with liberator but I am stuck on the following error.
Here is my code that starts the webserver and defines the routes:
(ns game-of-life.core
(:require
[ring.util.response :as resp]
[compojure.route :as route]
[ring.adapter.jetty :as jetty])
(:use
[ring.middleware.multipart-params :only [wrap-multipart-params]]
[ring.util.response :only [header]]
[compojure.core :only [context ANY routes defroutes]]
[compojure.handler :only [api]]))
(defn assemble-routes []
(->
(routes
(ANY "/" [] (resp/redirect "/index.html"))
(route/resources "/"))))
(def handler
(-> (assemble-routes))
(defn start [options]
(jetty/run-jetty #'handler (assoc options :join? false)))
(defn -main
([port]
(start {:port (Integer/parseInt port)}))
([]
(-main "3000")))
When I run lein ring server, I get a java.lang.NullPointerException with the following stacktrace:
reload.clj:18 ring.middleware.reload/wrap-reload[fn]
stacktrace.clj:17 ring.middleware.stacktrace/wrap-stacktrace-log[fn]
stacktrace.clj:80 ring.middleware.stacktrace/wrap-stacktrace-web[fn]
jetty.clj:18 ring.adapter.jetty/proxy-handler[fn] (Unknown
Source) ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$0.handle
HandlerWrapper.java:116 org.eclipse.jetty.server.handler.HandlerWrapper.handle
Server.java:363 org.eclipse.jetty.server.Server.handle
AbstractHttpConnection.java:483 org.eclipse.jetty.server.AbstractHttpConnection.handleRequest
AbstractHttpConnection.java:920 org.eclipse.jetty.server.AbstractHttpConnection.headerComplete
AbstractHttpConnection.java:982 org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete
HttpParser.java:635 org.eclipse.jetty.http.HttpParser.parseNext
HttpParser.java:235 org.eclipse.jetty.http.HttpParser.parseAvailable
AsyncHttpConnection.java:82 org.eclipse.jetty.server.AsyncHttpConnection.handle
SelectChannelEndPoint.java:628 org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle
SelectChannelEndPoint.java:52 org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run
QueuedThreadPool.java:608 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob
QueuedThreadPool.java:543 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run
Thread.java:744 java.lang.Thread.run
I think it will work better if your handler function get the request argument.
Can you try changing the dependencies like this? These versions and the following config totally works for me: (including reloading)
(defproject ..........
:dependencies [[org.clojure/clojure "1.5.1"]
[liberator "0.11.0"]
[ring/ring-core "1.1.8"]
[ring/ring-jetty-adapter "1.1.8"]
[compojure "1.1.3"]]
:main game-of-life.core
:min-lein-version "2.0.0"
:plugins [[lein-ring "0.8.10"]]
:ring {:handler game-of-life.core/handler})
Plus the handler should be
(def handler
(-> (assemble-routes)))
I am running Lein 2 and cider 0.7.0. I made a sample ring app that uses ring/run-jetty to start.
(ns nimbus-admin.handler
(:require [compojure.core :refer :all]
[compojure.handler :as handler]
[clojure.tools.nrepl.server :as nrepl-server]
[cider.nrepl :refer (cider-nrepl-handler)]
[ring.adapter.jetty :as ring]
[clojure.tools.trace :refer [trace]]
[ring.util.response :refer [resource-response response redirect content-type]]
[compojure.route :as route])
(:gen-class))
(defroutes app-routes
(GET "/blah" req "blah")
(route/resources "/")
(route/not-found (trace "not-found" "Not Found")))
(def app (handler/site app-routes))
(defn start-nrepl-server []
(nrepl-server/start-server :port 7888 :handler cider-nrepl-handler))
(defn start-jetty [ip port]
(ring/run-jetty app {:port port :ip ip}))
(defn -main
([] (-main 8080 "0.0.0.0"))
([port ip & args]
(let [port (Integer. port)]
(start-nrepl-server)
(start-jetty ip port))))
then connect to it with cider like:
cider-connect 127.0.0.1 7888
I can navigate to my site and eval forms in emacs and it will update what is running live in my nrepl session, so that is great.
I cannot see output, either with (print "test") (println "test") (trace "out" 1)
Finally, my project file:
(defproject nimbus-admin "0.1.0"
:description ""
:url ""
:min-lein-version "2.0.0"
:dependencies [[org.clojure/clojure "1.6.0"]
[com.climate/clj-newrelic "0.1.1"]
[com.ashafa/clutch "0.4.0-RC1"]
[ring "1.3.1"]
[clj-time "0.8.0"]
[midje "1.6.3"]
[org.clojure/tools.nrepl "0.2.6"]
[ring/ring-json "0.3.1"]
[org.clojure/tools.trace "0.7.8"]
[compojure "1.1.9"]
[org.clojure/data.json "0.2.5"]
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
]
:plugins [[lein-environ "1.0.0"]
[cider/cider-nrepl "0.7.0"]]
:main nimbus-admin.handler)
I start the site with lein run
Edit
I CAN see output, ONLY when using (.println System/out msg)
Have you tried (.println System/out msg)? I had the same problem and this worked for me.
It's possible to just put print statements in your code manually.
If you want to print information about each request, you can add middleware.
The handler you pass to jetty is a function from Ring requests to Ring responses.
Ring request and responses are just maps, see the Ring spec for more which keys they should contain.
Middleware is just a function that takes a handler as its first argument and returns a handler.
Example of a middleware function to print basic info about requests and responses:
(defn log-middleware [handler]
(fn [request]
(let [response (handler request)]
(println "=>" (name (:request-method request)) ":" (:uri request))
(println "<=" (:status request))
response)))
This middleware should print to the cider repl buffer, but cider behaves strangely
sometimes and send output to *Messages* or the nrepl server buffer.
You use this middleware by applying it to your handlers:
(def application (log-middleware (handler/site routes)))
Headers could be printed this way to: just get the :headers field form the request map and print it.
The Prone library may help you out. It is has a ring middleware for better exception reporting that also has the ability for debugging. When debugging, you can inspect any local bindings as well as the Ring request.
Here is a video that demonstrates how it works
Use (flush) after your print expressions to force output.