Fork me on GitHub

when running an uberjar web server locally via java -jar app.jar'' all is well... when running it the same way on ec2 it returns a resource not found error as it can't find resources in resources/public inside the jar; if I create a resources/public/<resources> on the server outside the jar, it works... why the difference, and how do I get the uberjar on the server to get the resources internally?


the resource is returned by a GET route in app-routes which in turn calls (defn get-page [] (slurp "resources/public/index.html")), if that's useful.


use io/resource, by default slurp will treat that as a filesystem path, io/resource treats it as a classpath relative path, which will work


-- How do you add a conditional inside a threading macro?

(-> {:env (:env options :dev)
     ::http/routes (route/expand-routes (graphql-routes compiled-schema options))
     ::http/port (:port options 8888)
     ::http/type :jetty
     ::http/join? false}
I saw that we could use cond->
 {:env (:env options :dev)
  ::http/routes (route/expand-routes (graphql-routes compiled-schema options))
  ::http/port (:port options 8888)
  ::http/type :jetty
  ::http/join? false}
  (:graphiql options) (assoc ::http/resource-path "graphiql")
  true http/create-server)
Or add a cond-> inside the threading macro
(-> {:env (:env options :dev)
     ::http/routes (route/expand-routes (graphql-routes compiled-schema options))
     ::http/port (:port options 8888)
     ::http/type :jetty
     ::http/join? false}
     (:graphiql options) (assoc ::http/resource-path "graphiql"))
How would handle conditional inside a threading macro?


I suspect you just need to be set straight on resources


resources are things you load via io/resource


slurp doesn't load resources


slurp loads files


resources are loaded from the classpath


in this case the resource folder is bundled in the jar with your code and available on the classpath


lein gives you a separate resources/ folder to put resources in, but technically anything available through a classloader is a resource (this includes anything in your jar, include clojure source files and or classfiles)


a common mistake is to load stuff out of resources/ as files only to have it break when you actually deploy stuff as a jar


if you ran your local jar not from inside your source checkout, you would have the same problem


when you run locally the reason it is working is you happen to be running in a directory with resources/ in it, you aren't correctly loading the resources from the out of the jar


thank you for helping... that sounds like the problem!


incidentally, I fortunately just looked at which points out you have to 'slurp directly on the result of io/resource' which I'll try now.


great! it all works now... thanks again!


also, watch out for io/resource returning nil when there's no resource found, you probably want to stop there instead of getting an NPE from slurp


Yeah, slurp can work on things that can be passed to io/reader, one of which is a URL, which io/resource returns.


I'm using to talk to a sqlite database. at one point I want to use str on a result of a (query ["select * from ..."]), but all I get is clojure.lang.LazySeq@323004b1. I've tried to wrap the query with doall, but it doesn't seem to matter. please send help


the toString of lazy-seq is pretty much useless, try "pr-str" instead of "str"


How about mapping str over that result?


@orestis I still get the lazyseq 😕


Sorry, try (mapv str (query ...))


You should at least get a vector back then.


eyy, what do you know, it works! thanks 🙂 a vector is fine, it's generally only 1 element so


didn't know about mapv either, so thanks for that as well! I'm guessing I can replace all (into [] (map with (mapv?


AFAIK, yes. But just FYI, if you have are expecting just a single element, then you should be able to do (first (query ...)). I’ve no idea about java.jdbc and how it’s supposed to work. It makes sense to return a lazy seq because usually SQL results map to some cursor in the DB, and you might want to consume that at your leisure. So be careful when eagerly consuming a Lazy Seq as it might give you more data than you expected 🙂


yeah, it should be a single element, but I don't want to make any assumptions, and in this particular case I'm throwing an error, so I felt I might as well include as much information as possible. 🙂


thanks anyway ^^

Ali Ebadian16:12:59

Hey all, I have a bit of a stupid question. What the point of the namespaces?


It just helps organize your functions and such so you can keep track of them.


It also makes it possible to re-use names, so you can have a foo/update function that does something different from a bar/update function (and the namespaces usually give some hint as to what that difference might be).

Ali Ebadian16:12:36

Not sure what is meant by organizing functions. What would disorganized functions look like?


have you worked on a project before?


take all of the files, cat them together, and then scramble theorder of the functions


“Organizing functions” as opposed to not having namespaces and having to write all your functions in one big file, each with a unique name, etc.

👍 4
Ali Ebadian16:12:45

@dpsutton No, just learning Clojure from ground up, hopefully then I find a job that uses it


i mean any programming project


any language. files, modules, directories. they all exist for our benefit, the code reader.


So in other words you can have a db namespace with a function called read that reads values from the database, and you can have a file namespace with a function called read that reads from files. There’s different code required for reading from files versus reading from databases, but it’s kinda doing the same sort of thing.

Alex Miller (Clojure team)16:12:06

there are a finite number of good names. namespaces let us use them in different contexts

👍 8

I’m using an example that’s kind of contrived, but you get the idea.


Hi, I have a requirement wherein I wanna read the inputstream twice. i.e., the body in my response. Apparently, if I use slurp then the stream will consumed. Currently, I am copying it to a new stream. Is there a better way of doing it ?


You can copy the stream to two destinations, but anything which consumes it will alter its state. Sometimes the reset method on streams works, but this isn't guaranteed for all stream implementations.


@akashhc depending on what you are doing with the stream, it's a lot easier to just use the ingested stream data again (eg. make a string first, then parse the string into data with json from the string)


@U051SS2EU Here is my scenario : I have my routes where in its consuming the stream and converting into a clojure map ( slurp and json decode basically). However, Now, I need to add a middleware during my sever start, where I need to check for some data in body and make decisions. I want to do this without changing my routes logic. So I need to read the stream twice.


You can attach the decoded data to the request object, there's standard middleware that does this for you


Where can I find a list of all of the types I can use with spec like string, int, etc. Also, should I be trying to model datetime in a spec or am I misusing spec here?


you can't use types in spec


spec operates on predicates


so not a "string" type, but the clojure.core/string? predicate


and you can use any arbitrary predicate in spec


most predicates in clojure.core have a defined mapping to some generator which is useful, if you use some other arbitrary predicate, if you want a generator you will have to provide one


Okay. I found in the clj-time repo that they have defined some predicates for date-time. Helpful


Bear in mind that clj-time is no longer recommended (I'm one of the maintainers). If you're on Java 8+, use the built in Java Time or a wrapper like


...depending on what you're trying to spec, Clojure has inst? built-in (with generators) and clojure.spec.alpha has inst-in and inst-in-range? that might be useful.


@kirankuppa I am not able to pull it up either. Hopefully it will be back up soon.


Can anyone direct me to more open source apps like


Looking to learn from more examples