Fork me on GitHub
#beginners
<
2017-09-16
>
mfm19:09:56

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.

mfm19:09:13

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

noisesmith19:09:20

make sure that resource path is on your classpath

noisesmith19:09:30

or use file instead of resource based operations to find the images

noisesmith19:09:14

so instead of java -jar [...].jar use java -cp [...].jar:resources my-app.main

noisesmith19:09:30

(for the resources option, which is the most convenient over all)

noisesmith19:09:09

where you substitute your actual ns containing -main for my-app.main of course

mfm19:09:42

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?

mfm19:09:27

i’ll look up the difference between java -cp and java -jar

noisesmith19:09:07

your uberjar doesn't know anything about your profiles

noisesmith19:09:16

the directory is not inside the jar, so java doesn't use it

noisesmith19:09:27

that config only affects what goes in the jar when you build it

noisesmith19:09:29

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)

mfm19:09:10

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.

noisesmith19:09:04

the running jar doesn't use your lein config at all

noisesmith19:09:20

lein is a tool that builds a jar, java at runtime knows nothing about the config lein used

noisesmith19:09:08

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

noisesmith19:09:33

which is why you have to configure java's classpath to see the directory

mfm19:09:56

oh right; i’m running java not lein to run the app. gotcha.

mfm19:09:07

thanks @noisesmith java -cp works.

noisesmith19:09:30

another fun trick is that you can run your uberjar to get a repl that can use all of your deps and namespaces

noisesmith19:09:06

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

noisesmith19:09:27

in a pinch I've used this to speed up debugging issues on remote servers

mfm19:09:29

oh that’s nice! saved.

rcustodio19:09:16

What is java -cp?

noisesmith19:09:07

it's the java command, with an argument specifying the class path (where it looks to find things)

noisesmith19:09:33

clojure is a java library, you can create a jar that runs directly from java without needing any other dependencies on your server

rcustodio19:09:39

I just use -jar

noisesmith19:09:21

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