Fork me on GitHub
Jakub Holý (HolyJak)13:11:34

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 :uberjar-exclusions #".*\.(clj|class)" and building the uberjar = dependencies only and a jar with just the code? Update: No, this with 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”]

Jakub Holý (HolyJak)14:11:05

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.

Jakub Holý (HolyJak)14:11:08

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

👍 4

@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


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)


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)


Looks like you know all this now though. So that was just for completeness then hah.

❤️ 4
Jakub Holý (HolyJak)15:11:13

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.


@holyjak eg.

:aliases {"jar" ["with-profile" "my-jar-profile" "jar"]}

❤️ 4
Jakub Holý (HolyJak)18:11:54

Thanks a lot, I didn't know about this.

🎉 4

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


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