The Boot REPL returns this error
java.lang.Exception: No namespace: com.walmartlabs.lacinia.internal-utils
clojure.lang.Compiler$CompilerException: java.lang.Exception: No namespace: com.walmartlabs.lacinia.internal-utils, compiling:(com/walmartlabs/lacinia/parser.clj:1:1)
when I try to run (require :reload 'entrypoint) in it. My namespace entrypoint has no code, only the :require function to import external code:
(ns entrypoint
"Application entrypoint."
(:require
[clojure.java.io :as io]
[com.walmartlabs.lacinia :as lacinia]
[io.pedestal.http :as http]
[clojure.java.browse :refer [browse-url]]
[clojure.edn :as edn]
[clojure.walk :as walk])
(:import (clojure.lang IPersistentMap)))
My build.boot looks like this:
(set-env!
:resource-paths #{"clj"}
:dependencies '[[org.clojure/clojure "1.9.0"]
[com.walmartlabs/lacinia "0.21.0"]
[io.aviso/logging "0.2.0"]])
What am I doing wrong? D:
My project was missing the boot.properties file.
I lost a couple of hours to notice this...
Related
The below is my app project.clj
(defproject clojure-my-app-api "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:ring {:handler clojure-my-app-api.core/app}
:dependencies [[org.clojure/clojure "1.8.0"]
[metosin/compojure-api "1.1.10"]
[ring/ring-core "1.4.0"]
[ring/ring-jetty-adapter "1.4.0"]]
:main clojure-my-app-api.core)
and my app core.clj is
(ns clojure-my-app-api.core
(:require [ring.adapter.jetty :as jetty])
(:require [compojure.api.sweet :refer :all])
(:require [ring.util.http-response :refer :all]))
(defapi app
(GET "/hello" []
:query-params [name :- String]
(ok {:message (str "Dear " name ", Hello I am here ")})))
(jetty/run-jetty app {:port 3000})
My doubt is, Is it mandatory to put (jetty/run-jetty app {:port 3000}) in every clj class if we have multiple classes for handling multiple API requests.
Can you please help me out is there any single main class mechanism for multiple clj class to handle different API path.
I have modified my code.
project.clj
(defproject clojure-dauble-business-api "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:ring {:handler {clojure-dauble-business-api.core/app
clojure-dauble-business-api.test/test1}}
:repl-options {:init-ns clojure-dauble-business-api.user}
:dependencies [[org.clojure/clojure "1.8.0"]
[metosin/compojure-api "1.1.10"]
[ring/ring-core "1.4.0"]
[ring/ring-jetty-adapter "1.4.0"]]
:main clojure-dauble-business-api.user)
user.clj
(ns clojure-dauble-business-api.user
(:require [ring.adapter.jetty :as jetty])
(:require [compojure.api.sweet :refer :all])
(:require [ring.util.http-response :refer :all])
(:require [clojure-dauble-business-api.core :as core])
(:require [clojure-dauble-business-api.test :as test]))
(jetty/run-jetty (list core/app test/test) {:port 3000})
core.clj
(ns clojure-dauble-business-api.core
(:require [ring.adapter.jetty :as jetty])
(:require [compojure.api.sweet :refer :all])
(:require [ring.util.http-response :refer :all]))
(defapi app
(GET "/hello" []
:query-params [name :- String]
(ok {:message (str "Dear " name ", Hello I am here ")})))
test.clj
(ns clojure-dauble-business-api.test
(:require [ring.adapter.jetty :as jetty])
(:require [compojure.api.sweet :refer :all])
(:require [ring.util.http-response :refer :all]))
(defapi test
(GET "/ping" []
:query-params [name :- String]
(ok {:message (str "Dear " name ", Hello I am here ")})))
Error while running http://localhost:3000/hello?name=acbd endpoint in Postman
2017-07-08 10:46:34.413:WARN:oejs.HttpChannel:qtp191004666-15: /hello?name=abcd
java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
at ring.adapter.jetty$proxy_handler$fn__1401.invoke(jetty.clj:24)
at ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
You shouldn't have (jetty/run-jetty (list core/app test/test) {:port 3000}) in any of your namespaces. (Having it in user.clj is fine for REPL work).
Typically, you have a single handler route that you pass to ring for handing your application.
For example, I generally have a routes namespace that I combine by routes from other namespaces.
So, from your example.
(ns clojure-dauble-business-api.routes
:require [compojure.core :refer :all]
(clojure-dauble-business-api [core :as core]
[test :as t]))
(def app
(routes core/app t/test))
This is what you could pass into Jetty, or refer to in your :ring entry in your project.clj.
:ring {:handler clojure-dauble-business-api.routes}
You're getting the error, because run-jetty must be passed a function, but you're passing it a list instead (because you're trying to consolidate your routes with (list core/app test/test)
I would also add the plugin lein-ring to your project and remove the :main entry. You will also have to correct your :ring entry in your project as above.
I am a newbie too, but hope this helps:
This is how I have implemented. There is one file named user.clj which has
(jetty/run-jetty app {:port 3000})
and other common function that you may specify in main and then in project.clj
:repl-options {:init-ns user}
you can also use injections to load namespaces but I have never used them.
I've a luminus project with some simple compojure-api routes.
I've added carmine to communicate with a redis server, using the wcar* macro (defined in services.clj) to make calls to it, and everything works fine.
Now I'm trying to add some tests, but seems that the redis connection doesn't works properly during them, because I'm receiving this error with lein test:
ERROR Carmine connection error
clojure.lang.ExceptionInfo: Carmine connection error {}
Since it's working in dev e prod environments, I think that is something related to a missing env load in the test environment, but I didn't find a way to solve it.
These are relevant parts of the code in use:
test.clj
(ns app.test.handler
(:require [clojure.test :refer :all]
[ring.mock.request :refer :all]
[app.handler :refer :all]))
(deftest test-app
(testing "redis ping"
(let [response ((app) (request :get "/api/redis-ping"))]
(is (= 200 (:status response))))))
services.clj
(ns app.routes.services
(:require [ring.util.http-response :refer :all]
[compojure.api.sweet :refer :all]
[schema.core :as s]
[app.config :refer [env]]
[clojure.tools.logging :as log]
[mount.core :refer [defstate]]
[taoensso.carmine :as car :refer (wcar)]))
(defmacro wcar* [& body] `(car/wcar
{:spec {:host (:redis-host env) :port (:redis-port env)}}
~#body))
(defapi service-routes
(context "/api" []
:tags ["myapi"]
(GET "/redis-ping" []
:return String
:summary "A redis client test."
(ok (wcar* (car/ping "hello"))))))
handler.clj
(ns app.handler
(:require [compojure.core :refer [routes wrap-routes]]
[app.routes.services :refer [service-routes]]
[compojure.route :as route]
[app.env :refer [defaults]]
[mount.core :as mount]
[app.middleware :as middleware]))
(mount/defstate init-app
:start ((or (:init defaults) identity))
:stop ((or (:stop defaults) identity)))
(def app-routes
(routes
#'service-routes
(route/not-found
"page not found")))
(defn app [] (middleware/wrap-base #'app-routes))
Profiles.clj
{:profiles/dev {:env {:redis-host "127.0.0.1" :redis-port 6381}}
:profiles/test {:env {:redis-host "127.0.0.1" :redis-port 6381}}}
Config.clj
(ns app.config
(:require [cprop.core :refer [load-config]]
[cprop.source :as source]
[mount.core :refer [args defstate]]))
(defstate env :start (load-config
:merge
[(args)
(source/from-system-props)
(source/from-env)]))
SOLUTION
Add a text fixture with the mount/start command that's executed before tests.
Add to test.clj:
(defn my-test-fixture [f]
(mount/start)
(f))
(use-fixtures :once my-test-fixture)
You are using mount to manage your application state lifecycle. I think you are not calling (mount/start) in your tests thus your app.config/env state is not initialized properly. On the other hand when you start your application (mount/start) is probably called and thus it's working correctly.
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)))
As webnoir got deprecated I've decided to migrate from fetch as described in docs, but for some reason shoreleave.remotes in not being compiled to Js and as a result I get
goog.require could not find: shoreleave.remotes.http_rpc
I've tried both remote-callback and remotes.macros. My ClojureScript namespace goes like this
(ns my.cljs.ns
(:require [shoreleave.remotes.http-rpc :as rpc])
(:require-macros [shoreleave.remotes.macros :as fm])
and backend
(ns my.backend
(:use my.views
(:require [compojure.route :as route]
[compojure.handler :as handler]
[cemerick.shoreleave.rpc :as rpc]))
)
(rpc/defremote get-data [last-changed]
[:foo]
)
(defroutes my-routes
(GET "/" [] (intro-view))
(route/files "/" {:root "resources/public"})
(route/not-found "<h1>Page not found</h1>"))
(def my-routing (-> #'my-routes
rpc/wrap-rpc
handler/site))
Any ideas how to get it working?
UPDATE: I found out that for some reason goog.require('shoreleave.remotes.http_rpc') goes before goog.provide('shoreleave.remotes.http_rpc')
it was a problem with incremental complition in lein (see bug CLJS-282), adding ':incremental false' in project.clj fixed my problem:
:cljsbuild {
:builds [{
:incremental false
:jar true
:source-path "src-cljs"
:compiler {
:output-to "resources/public/js/js.js"
:optimizations :whitespace
:pretty-print true}
}]}
I just solved this problem by adding two dependencies in project.clj.
[shoreleave "0.3.0"]
[shoreleave/shoreleave-remote "0.3.0"]
I'm executing lein uberwar for my test webapp and I'm getting the following weird error:
Exception in thread "main" java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.Symbol (servlet.clj:1)
The servlet.clj contains the following:
(ns test.servlet
(:use ring.util.servlet)
(:require test.routes :as routes)
(:gen-class :extends javax.servlet.http.HttpServlet))
(defservice routes/app-routes)
The test.routes file contains:
(ns test.routes
(:use compojure.core)
(:require [compojure.route :as route]
[compojure.handler :as handler]))
(defroutes app-routes
(GET "/" [] {:status 200
:headers {"Content-Type" "text/html"}
:body "<h1>Hello World</h1>"})
(route/files "/" {:root "static"})
(ANY "/:s" [s] (str "page-not-found" s)
;; For lein ring-server
;(def test-handler
; (handler/site app-routes))
The strange thing is that if I substitute the line
(:require test.routes :as routes)
With:
(:require test.routes)
And call
(defservice test.routes/app-routes)
In servlet.clj, the WAR compiles fine and it is working flawlessly in tomcat. Is there some bug in my code that I fail to see? Why do I need to call test.routes/... instead of just routes/...?
You need to put it inside a vector:
(:require [test.routes :as routes])