tools-build

cjohansen 2024-12-02T13:47:23.703099Z

We're using the discontinued https://github.com/EwenG/badigeon to build our production artifact, and just spent some time https://clojurians.slack.com/archives/C6QH853H8/p1733141434385289 on the fact that it uses tools.deps.alpha 🙈 The main reason we're using badigeon is its bundle function, which does the following: > Creates a standalone bundle of the project resources and its dependencies. By default jar dependencies are copied in a \"lib\" folder, under the ouput directory. Other dependencies (local and git) are copied by copying their :paths content to the root of the output directory. Resource conflicts (multiple resources with the same path) are not copied to the output directory. By default, an exception is thrown when the project dependends on a local dependency or a SNAPSHOT version of a dependency. Does tools.build have something similar?

Alex Miller (Clojure team) 2024-12-02T13:58:09.579229Z

not directly, although it has all the pieces there. the create-basis task returns the basis, which includes :libs, which is a map that includes all of the jars and paths that would end up on the classpath and their source type. The copy-file and copy-dir task exist to move files around, and jar and zip exist to make archives.

cjohansen 2024-12-02T14:00:06.224009Z

Ah, so create-basis sounds like the missing piece from the last time I attempted to port this build 😊 Then I think it'll be fairly straight-forward to port this.

Alex Miller (Clojure team) 2024-12-02T14:00:25.359719Z

or the uber task builds an uber jar, which is a standalone bundle that combines libs and paths from git or local deps and does resource conflict management

Alex Miller (Clojure team) 2024-12-02T14:01:21.858019Z

create-basis has always been part of tools.build as that is the heart of tools.deps, which tools.build depends on

cjohansen 2024-12-02T14:01:42.292689Z

Yeah, this is more a case of me not finding it!

cjohansen 2024-12-02T14:02:32.701799Z

uber is close to what I want, I just don't want the extra level of jar-ing. We wrap things up in a Docker image anyway, and I find it easier to troubleshoot without the extra level of packaging.

Alex Miller (Clojure team) 2024-12-02T14:03:31.525909Z

so you want a set of jars, one of which is the file stuff?

Alex Miller (Clojure team) 2024-12-02T14:04:58.029579Z

how do you actually use the bundle to start your app, out of curiosity- is it a classpath wildcard kind of thing?

cjohansen 2024-12-02T14:07:06.190279Z

FROM eclipse-temurin:21-jre-alpine

ADD target/jars /app/lib
ADD target/classes /app/classes
COPY config /app/config

WORKDIR /app

CMD exec java $JVM_OPTS -cp "classes:lib/*" ourapp.prod
Like so

👍 1
cjohansen 2024-12-02T14:07:37.387229Z

target/jars is the result of badigeon's bundle operation, and target/classes is the result of compile.

cjohansen 2024-12-02T14:11:18.192329Z

This is basically as low tech of a production build I can imagine. Very "inspectable" and easy to verify locally.

Alex Miller (Clojure team) 2024-12-02T14:25:12.107559Z

yep, I get it

Alex Miller (Clojure team) 2024-12-02T14:25:44.244529Z

it's very similar to what datomic ions does under the hood

cjohansen 2024-12-02T14:29:53.508149Z

😊 👍

Alex Miller (Clojure team) 2024-12-02T14:31:11.335889Z

I think they do some additional stuff to only deploy the delta jars rather than all the jars to reduce traffic

cjohansen 2024-12-02T14:31:59.865139Z

I can see how that would be very useful for them.

dpsutton 2024-12-02T02:50:47.166209Z

We’ve been on depstar for a while and finally moving over. Our jars seem to have corrupted logging ever since. I see depstar does some special merging on our behalf (thanks!). (context: https://github.com/seancorfield/depstar/blob/develop/src/hf/depstar/uberjar.clj#L151-L166). Is there an equivalent solution in tools.build? I’m not seeing anything coming up greping the codebase and don’t remember seeing or hearing anything like that.

dpsutton 2024-12-02T02:52:56.558659Z

I take it there should be some conflict handlers for this. I guess we should write our own? Anyone know of any prior art here?

dpsutton 2024-12-02T02:54:22.200679Z

I’ve just searched and found the solution! I’m sorry i should have searched first

seancorfield 2024-12-02T03:18:43.596569Z

I gather you found this? https://github.com/seancorfield/build-uber-log4j2-handler

dpsutton 2024-12-02T03:18:58.205149Z

yes i did! thank you!

dpsutton 2024-12-02T03:19:14.951439Z

hadn’t heard any chatter of it. i should have searched first

seancorfield 2024-12-02T03:19:21.875679Z

Any suggestions on how I could have made it more discoverable?

dpsutton 2024-12-02T03:20:36.912319Z

i’m not sure. my steps were i googled part of the weird logging message and ended up here: https://stackoverflow.com/questions/48033792/log4j2-error-statuslogger-unrecognized-conversion-specifier Then checked depstar source and then went to tools.build to see if there was something built in there.

seancorfield 2024-12-02T03:20:55.631839Z

This talks about it, and is linked from the tools.build guide: https://clojure-doc.org/articles/cookbooks/cli_build_projects/

dpsutton 2024-12-02T03:21:27.131659Z

that’s good to know! I’ll need to reread it.

dpsutton 2024-12-02T03:22:58.435219Z

The exact thing i googled was “ERROR Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.” I wonder what i might have tried? I didn’t think the error message would hit with any clojure keywords. And the error doesn’t really point to what might have caused it.

seancorfield 2024-12-02T03:23:24.349769Z

The actual error you get depends on a lot of things, unfortunately.

dpsutton 2024-12-02T03:23:40.152759Z

yeah. it’s a very “upstream” type of bug

seancorfield 2024-12-02T03:24:43.254439Z

What happens, without the cache merging, is that you randomly get one of the multiple plugin caches from the classpath, which means you get a random subset of the log4j features you expect -- so any particular feature could be the one that fails 😞

dpsutton 2024-12-02T03:25:53.834879Z

I get why this isn’t part of tools.build because of the dep. But it almost seems such a critical piece maybe it merits a callout in the readme there?

seancorfield 2024-12-02T03:27:22.605559Z

Yeah, it's one of those things that you only need if you use log4j2 and only if you depend on multiple libraries that supply plugins... which is a pretty narrow set of apps... but if you need it, you must use it!

dpsutton 2024-12-02T03:28:15.703389Z

i would expect almost every uberjar these days to need this? I wish i could easily see which jars brought in plugins

seancorfield 2024-12-02T03:28:56.498359Z

The only consolation is that this will all go away in log4j 3.x 🙂

dpsutton 2024-12-02T03:29:09.691489Z

haha. yeah i saw the todo in depstar

dpsutton 2024-12-02T03:29:31.341089Z

"Log4j2 has a very problematic binary plugins cache file that needs to
  be merged -- but it's going away in 3.0.0 apparently because it keeps
  breaking build tools... We use log4j's plugin processor to merge it."

seancorfield 2024-12-02T03:32:40.965319Z

The depstar README says "The missing piece (for us at work) had been the merging of the Log4j2Plugins.dat files across libraries which depstar had supported since December 2020 (version 2.0.160) and that is now possible through the :conflict-handlers option added to uber in v0.4.0 of tools.build, along with my log4j2 conflict handler library."

dpsutton 2024-12-02T03:34:34.923599Z

ooh. that’s a great bit. I think if it had been in a big “migration guide” section or some kind of alert callout that everything works the same except this one piece we might have noticed it. But not sure 🙂 Sometimes you just jump in despite so much helpful documentation 🤠

seancorfield 2024-12-02T03:35:26.917289Z

It's archived so I can't easily edit that... I'd have to unarchive, edit it, and re-archive 🙂

dpsutton 2024-12-02T03:35:53.346699Z

dang. you’d think a change to a readme would be easy for archived stuff

seancorfield 2024-12-02T03:43:13.698859Z

I unarchived it and edited it. Does this help? https://github.com/seancorfield/depstar/blob/develop/README.md

seancorfield 2024-12-02T03:43:47.463299Z

(I also took the opportunity to remove the recommendation to use my build-clj library, which I've since archived too!)

dpsutton 2024-12-02T03:44:32.454799Z

yeah that looks super helpful!

👍🏻 1