Hello! Is there any good way to build a .jar of my code + a jar of all dependencies? (i.e. essentially split the uberjar into my code and dependencies)
The reason is that I bake it into a Docker image and while my code changes frequently, the dependencies don't and I can get much faster upload if I split them. Thank you!
(Perhaps Update: No, this with :uberjar-exclusions #".*\.(clj|class)"
and building the uberjar = dependencies only and a jar with just the code?exclusions
does not work.)
Update: I have tried the following to build an uberjar with only dependencies but it does not work, it still has my code when I run lein uberjar
:
:target-path "target/%s/"
:jar-name "myapp.jar"
:profiles {:uberjar {:uberjar-name "myapp-dependencies.jar"
:source-paths ["no-such-dir"] :resource-paths ["no-such-dir"] :main nil :aot []}}
=> target/uberjar/myapp-dependencies.jar
still contains myapp/*
@holyjak not sure if it’ll be 100% what you want but add ^:replace metadata to both paths vectors
Eg
^:replace [“no-such-dir”]
Thank you! It helped! (I just had to move :aot, :main
from the settings into a separate profile because I cannot override them in the uberjar
profile, at least not like this: :main ^:replace nil
(for obvious reasons))
So now I have to run lein uberjar
and lein with-profile jar jar
to get the 2 files I want.
Now I just need to figure out how to produce both jar and uberjar without lein deleting the former when producing the latter 🙂 (I suppose :auto-clean false
will fix that)
@holyjak yes. Makes sense I think. The auto-clean thing can be a pain to work with.
I think you’ll have to be sure no auto clean is active and your target-path includes profile name in it so the jar and uberjar created do not clash
Thanks a lot!
@holyjak I was typing from a mobile when I said last thing (so kept it brief), but the example of the :target-path
thing is
https://github.com/technomancy/leiningen/blob/stable/sample.project.clj#L309-L313
The idea being that the jar
task and the uberjar
task would use different subdirs for their output under the target/
dir. with :auto-clean false
then they wouldn’t delete each other, but the jar that uberjar
makes wouldn’t override the jar the jar
tasks creates (assuming you have them both mapping to the same jar name)
Thx I have it
if that isn’t clear enough, keep in mind that the uberjar
tasks actually produces 2 artifacts, the uberjar (ie. typically “standalone” classifier used in name) and the normal jar that was created for the purpose of the uberjar (so using the profiles you have active at the time of uberjar
)
cool
Looks like you know all this now though. So that was just for completeness then hah.
It would be great if there was a built in jar profile as is the case with uberjar...
@holyjak yeah perhaps. Or you could say it’s odd there is a special task-built-in profile for uberjar. Hah
Well test and repl are similar though. So maybe jar is left out
You can use an alias in your project to hide it on the cmd line if that helps though
Such as if you have tooling with builds where it’s hard to add project (generically perhaps) profiles to cmd args.
Thanks a lot, I didn't know about this.
Hoping someone can give me ideas of things to check: I'm setting up a new machine (windows 10) and getting my tools installed. I have Java installed (I've tried amazon corretto and the oracle openjdk). Downloaded lein.bat and put it in my personal bin directory, which is on the path. Set HTTP_CLIENT to use curl (using the instructions it gave me when it failed). ran lein self-install. Seemed to install ok. When I run lein (using any subcommand or none at all) it prints "access is denied". Turning on echo in lein.bat shows that it is running java, and this is being printed from within the java run. Tried setting DEBUG=true in my environment to get a stack trace, but that didn't work. I have no idea what it's trying to access. Given I'm just setting up the machine, I can believe there's a permission issue, but I don't know where to look.
@terry.poot you are sure you set the DEBUG=true
correctly?
did you see any extra info when you did that at least?
The bat file showed me the classpath, but nothing from within the java/clojure code
I set it in my environment and also with a set command from the command line
whether either of those is correct I'm not completely certain 🙂
yeah, doing the same on my working system gives me an extra message telling the task it's running, so I did set DEBUG correctly, so it's failing before that message, and it's not hitting the exception handler in main or it would print a stack trace
ok, interesting
I wonder if the Java cmd could have a flag passed for more info perhaps or something like that
something coming from Java perhaps
I haven't found such a thing. I'm trying to use process monitor to see what's being accessed, but it's at the windows level so there's a mountain of results, and I'm trying to find a significant difference between the working and non-working machine. No luck so far. Something at the java level would be really helpful, but I'm not aware of such a thing
long shot, but perhaps anything in an fatal error log ? https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/felog001.html#BABIDHJC
also, be sure the project directory has a :target-path
that is a directory you’ll have permissions to write to
I'll give that a try in a minute. I just noticed from procmon that it's trying to access all the command line arguments as files (i.e. the -Dclojure.compile=path stuff), which my other machine doesn't do. That's way weird
yeah, I created one, but right now I'm trying to run it in a non-project directory, which should totally work. and use a bunch of defaults. I figured less things to trip over.
yeah, that's the difference. The non-working one tries to find every one of the command line arguments as a file. The working one doesn't. And if it's trying to find them as a file, it's undoubtedly failing to evaluate them as arguments. Dunno why, but it kinda seems that has to be the basic issue
you sure you installed lein right and are using a supported shell?
I don’t know here - I haven’t even used it on windows
Pretty sure. I've done it a number of times. Right now I'm thinking it's one of the weird windows "this came from the internet so we don't trust it" things, or something like that. If I run JUST the java command with the correct arguments (gotten from watching the bat file run), the working machine just runs java, no scanning arguments or anything. The one that doesn't gives some sort of file locked error and then scans the arguments as files trying to find them all. So, for whatever reason, java is misbehaving here. Weird though, because "java -version" works just fine. I'll still go try the java error log thing if this doesn't pan out, but right now I'm searching for windows weirdnesses that might be relevant.
Anyway, thank you so much for your help.
I guess you are sure that lein
is using the same version of java
that you are using when you try to recreate?
yeah, I set LEIN_JAVA_CMD to point to java.exe, and I can see it running that one from the bat file echo
perhaps LEIN_JAVA_CMD
and/or the :jvm-cmd
project flag are relevant
ok