This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-18
Channels
- # announcements (2)
- # aws (3)
- # beginners (35)
- # boot (10)
- # cider (33)
- # cljs-dev (22)
- # clojure (58)
- # clojure-belgium (1)
- # clojure-europe (8)
- # clojure-houston (1)
- # clojure-italy (47)
- # clojure-nl (2)
- # clojure-spec (4)
- # clojure-uk (39)
- # clojurescript (12)
- # cursive (18)
- # data-science (1)
- # datomic (2)
- # emacs (24)
- # figwheel-main (29)
- # fulcro (24)
- # hoplon (14)
- # juxt (6)
- # kaocha (3)
- # nrepl (6)
- # off-topic (64)
- # om (1)
- # om-next (1)
- # pathom (21)
- # pedestal (18)
- # planck (40)
- # protorepl (1)
- # re-frame (15)
- # reagent (7)
- # reitit (16)
- # shadow-cljs (184)
- # spacemacs (4)
- # test-check (33)
Good morning guys. I really would appreciate some help configuring gradle-clojure plugin on a Grails project. Is there anyone out there with some experience on that?
Have you looked at the output of the stacktrace (as described in the answer here: https://stackoverflow.com/questions/51139153/kotlin-plugin-error-could-not-generate-a-proxy-class-for-class-mytask#51139154)?
Hi, anyone have experience integrating Clojure into an existing java code base workflow? In order to get buy in for bringing in Clojure into our code base I need to demonstrate that it can be part of our build process and that if/when other people start to contribute Clojure code the build process would at least catch any compile-time errors. Realize that this is going against the dynamic nature of Clojure and since at the moment I’m the only one using the language there’s not much of a benefit but from a business risk mitigation perspective it makes sense. I’m looking at the ahead-of-time compiler and/or just calling load-file
or load-script
on all *.clj files in the build tree. Anyone have experience doing this? Any suggestions what the best approach would be? Thanks in advance.
I’d suggest using aot, and building a jar artifact that you include like any other artifact
the big question is about how people call into this code. You can use the Clojure Java API (http://clojure.github.io/clojure/javadoc/clojure/java/api/package-frame.html) but it's pretty low-level. The ideal is to actually have well-defined Java interfaces (in Java) with docstring etc and then just have Clojure provide the implementation. That way consumers largely don't know or care that it's Clojure.
thank you @U064X3EF3!
I would be interested in how you manage this, @UA1L0L4M7. My situation may be similar --- we have a Java app at work, and I'm the new quality engineer. I am much more familiar with Clojure than Java, and I am interested in developing, like, a "testing" build of our app that does some generative testing on the objects my co-workers make. But I haven't yet put in the work to figure out how gradle and the Java build chain operate.
Hello everybody, I am a clojure newbie so every advice on how I am writing this at any level would be more than useful. I am building a small server with http-kit
that writes on a mongo db
The main file is the server, which calls default-push
in order to push data into the mongodb:
(ns skincare-server.core
(:gen-class)
(:require [org.httpkit.server :as http-server]
[clj-time.local :as l]
[compojure.core :refer :all]
[compojure.route :as route]
[compojure.handler :as handler]
[skincare_server.database :refer [default-push]]
[ring.middleware.json :refer [wrap-json-body wrap-json-response]]
[ring.util.response :only [response]]
))
(def port 8000)
(defn handle-push-data
[request]
(let
[decorated-request (assoc request :time (str (l/local-now)))
document (default-push decorated-request)]
{:status 200 :body document}))
(defroutes app-routes
(GET "/" [] "Maronn, I am running! Try cache me!")
(POST "/post-data" req (handle-push-data req))
(route/not-found "404 page not found"))
(def app
(-> (handler/site app-routes)
(wrap-json-body)
(wrap-json-response)
))
(defn -main [& args]
(http-server/run-server app {:port port})
(println (format "Server started on port %s" port)))
And in this file I define the function to write on mongo.
(ns skincare_server.database
(:require [monger.core :as mg]
[monger.collection :as mc]
[dotenv :refer [env]])
(:import [org.bson.types ObjectId]))
;; Connects to default port
(defn mongo-pusher-factory
"A factory that returns a function that pushes onto mongo"
[& [dbname collection-name]]
(let [dbname (or dbname (env "DB_NAME"))
collection-name (or collection-name (env "COLLECTION_NAME"))
conn (mg/connect)
db (mg/get-db conn dbname)]
(fn [post-data]
(let [post (assoc post-data :_id (ObjectId.))
document (mc/insert-and-return db collection-name post)]
document))))
(def default-push (mongo-pusher-factory))
The code compiles and all good until, when i get a POST request it raises
Mon Feb 18 21:22:50 CET 2019 [worker-1] ERROR - POST /post-data
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class org.httpkit.server.AsyncChannel.
My interpreting Java errors is not the best so i can’t figure out where the mistake is. Thank you for your help!It could be badly written but I thought that: (let [dbname (or dbname (env "DB_NAME")])
defaults to the env variable such that e.g. DB_NAME=test
in .env
Thank you for your help, I tried to read through this error but it isn’t that clear what is happening.
ok. so it looks like you are correctly getting things into monger. so the problem is you are getting the wrong thing there
you're putting the entire request object into it. maybe rather than inserting things, return the post-data as json so you can see what you are actually doing
your handler assoces a time onto the request and then passes that into your monger stuff, which stamps an id (on the request, not the post-data) and tries to put that big thing into the db. you probably need to grab the post params out of it
So I've setup this clojure project in lein with the default template, but I'm getting some exceptions when I use Java 11. It works fine with Java 8.
/usr/lib/jvm/java-11-openjdk/bin/java ...
Exception in thread "main" Syntax error compiling at (org/httpkit/server.clj:1:1).
at backend.core$eval138$loading__6706__auto____139.invoke(core.clj:16)
at backend.core$eval138.invokeStatic(core.clj:16)
at backend.core$eval138.invoke(core.clj:16)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at clojure.lang.RT.classForName(RT.java:2207)
at clojure.lang.RT.classForNameNonLoading(RT.java:2220)
at org.httpkit.server$eval144$loading__6706__auto____145.invoke(server.clj:1)
at org.httpkit.server$eval144.invokeStatic(server.clj:1)
at org.httpkit.server$eval144.invoke(server.clj:1)
This is the only code I have atm except the default test lein generates and a resource folder with a json file in it
@UFSTV75C6 Clojure supports it, yes. What version of Leiningen are you using? lein version
As of Java 9, xml.bind was classified as a Java EE package and its module was not loaded automatically in the jdk. It was removed entirely from the JDK distribution in Java 11, so you need to bring it in explicitly as either a module or a lib.
Is it a good idea to avoid loop/recur and use simple function call recursion when I only need it to recur a hand full of times?
For some context I'm making a http request that could fail and I want to wait and retry up to 5 times
@caleb.macdonaldblack I would say, in that case, whatever you find most readable.
I have functions at work that do exactly that and most do it as a simple recursive call, passing the number of retries made so far or a flag indicating whether a retry should be done (for places where we perform a single retry). But then the retry count/flag needs to be exposed in the functions arguments so that's a trade off.
We also have functions that do that internally via loop
/`recur` -- which I find easier to read overall (since it's an internal implementation detail).
Actually after considering a simple recursive call for retry I ran into exactly that. The binding for loop/recur is really useful for keeping a count and keeps it out of the function args