This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-09-16
Channels
- # aleph (1)
- # aws (2)
- # bangalore-clj (2)
- # beginners (33)
- # cider (3)
- # cljs-dev (4)
- # cljs-experience (6)
- # cljsjs (1)
- # cljsrn (8)
- # clojure (84)
- # clojure-sanfrancisco (1)
- # clojure-spec (6)
- # clojure-uk (5)
- # clojurescript (42)
- # defnpodcast (3)
- # docs (3)
- # emacs (13)
- # events (1)
- # fulcro (2)
- # hoplon (19)
- # liberator (2)
- # off-topic (5)
- # onyx (7)
- # parinfer (1)
- # pedestal (1)
- # re-frame (13)
- # ring-swagger (13)
- # spacemacs (19)
- # yada (2)
i use lein uberjar
for production deployments, then java -jar [...].jar
. I have a web app where you can upload images. they get put in $proj_dir/resources/images
.
for the longest time i couldn’t figure out why images that were uploaded during a production deployment wouldn’t show up, but when run in dev mode, they did show up. then, i jar tf [...].jar
‘d the uberjar.
lein uberjar
includes all the images in ./resources/images
. so when the production app is running, images are correctly being saved to disk, but because they’re not in the uberjar, they don’t show up in my webapp.
question: how do i get what i want? is there an option in project.clj
? i’m not very familiar with project.clj
or lein
. i want to be able to read from that directory when running my production app.
i diagnosed the problem after realizing that i can see all previously-uploaded images after i lein uberjar
. and i can see all images--no matter what--when running via lein repl
make sure that resource path is on your classpath
or use file instead of resource based operations to find the images
so instead of java -jar [...].jar
use java -cp [...].jar:resources my-app.main
(for the resources option, which is the most convenient over all)
where you substitute your actual ns containing -main
for my-app.main
of course
when you say “make sure that resource path is on your classpath”: my :profiles options for :uberjar are:
{:omit-source true
:aot :all
:uberjar-name "conus.jar"
:source-paths ["env/prod/clj"]
:resource-paths ["env/prod/resources"]}
you’re saying put "resources"
in :resource-paths
?your uberjar doesn't know anything about your profiles
the directory is not inside the jar, so java doesn't use it
that config only affects what goes in the jar when you build it
the difference between -cp
and -jar
is that one of them lets you specify a custom class path (and then requires manually saying which class to run, since there's no one jar to use as a default)
ah, so adding "resources"
into the the :resource-paths
won’t help, because the running jar can’t read at run-time from resources/images
? sorry to need to be so explicit; this is all new to me.
the running jar doesn't use your lein config at all
lein is a tool that builds a jar, java at runtime knows nothing about the config lein used
the jar can read from resources/images, if you tell it to, but just having it in lein config doesn't do anything to change the behavior of the runtime jar executed by java
which is why you have to configure java's classpath to see the directory
thanks @noisesmith java -cp
works.
another fun trick is that you can run your uberjar to get a repl that can use all of your deps and namespaces
java -cp my.uber.jar clojure.main
- optionally rlwrap java -cp my.uber.jar clojure.main
on a *nix to get command line editing and history too
in a pinch I've used this to speed up debugging issues on remote servers
it's the java command, with an argument specifying the class path (where it looks to find things)
clojure is a java library, you can create a jar that runs directly from java without needing any other dependencies on your server
right, if you follow the conversation back, @mfm needed to read some things from disk, and others from inside the jar, with the same code, and setting cp simplifies that