Fork me on GitHub
#boot
<
2018-05-16
>
mariuene09:05:48

Hey, I have a problem with loading packages. It seams like if I specify a snapshot version of a package with a version, timestamp, and build-number, like "1.2.3-20180516.090000-3", boot will default to the first version of that package loaded, which it has stored in .boot/cahce From what I can understand it looks like boot doesn't look at the maven directory if a snapshot is updated, and just uses the one it has stored in its cache. and for comparison maven updates the package correctly so that the "1.2.3-20180516.090000-3" version is the same as the "1.2.3-SNAPSHOT" in the .m2 directory. A brute force way I found to solve this issue is to delete the boot cache and relaunch the application so boot reloads every package from maven again.

danm10:05:21

That's interesting. If I do a boot build install of a snapshot version of a lib with the same version string my projects use the new version correctly

mariuene10:05:19

yes, I've tested it with at different lib and it works for that. The only difference I can see now is that we use the :add-jar option for sift for the lib I am having problems with.

danm16:05:10

Is there a way in boot to support multiple versions of the same lib in the same project? Like, I am writing a script that imports 2 Clojure libs - A and B. A and B both depend on C, but A depends on version 1.8 and B depends on version 2.1 (as a contrived example), and there are breaking changes between the two versions of C

Alex Miller (Clojure team)16:05:53

this can only by solved through the use of classloaders to isolate usage

danm16:05:59

As things stand at the moment, boot seems to download the version for whichever lib is first in the build.boot dependencies list, and then throw an error for the other lib when I try and call a function that doesn't exist

danm16:05:13

Right. Hmm, I will have to look into that in more detail

Alex Miller (Clojure team)16:05:59

you can use various pod/classloader isolation libs to skin that problem in your code by building isolated parts of your code that use one or the other. generally, that’s a traumatic and/or impossible change.

danm16:05:20

Fair enough

Alex Miller (Clojure team)16:05:26

and this is why Rich has been pushing so hard to move the Clojure community to a model where we don’t make breaking changes

Alex Miller (Clojure team)16:05:13

in reality, what most people do is to try to coax A and or B to use compatible versions of C. or cut one of the deps to avoid the conflict.

Alex Miller (Clojure team)16:05:13

this is aka “jar hell”

Alex Miller (Clojure team)16:05:52

this is an entire genre of problem that we (as an industry) have inflicted upon ourselves

danm16:05:18

In this particular instance it's a fairly easy fix, as A, B and C are all actually internal libs, so we can just update all of them to be compatible. But we have come across a simpler version of this problem before with external libs. Luckily it was fixed by just changing the dependency order so we pull in the newest version first

danm16:05:42

But I await the time that is not a valid fix with much trepidation

Alex Miller (Clojure team)16:05:05

the clj dependency algorithm is different than maven’s and will effectively try to use the newest version as much as possible

danm16:05:23

I was going to say that wasn't our experience, but that may be because we were using Amazonica, and the issue was actually with the Java libs it pulls in and then wraps. Or should that not matter?

Alex Miller (Clojure team)16:05:07

deps stuff doesn’t have any knowledge of Clojure vs Java, but I am stating a high-level intent and the details matter a lot as to what you’ll see

Alex Miller (Clojure team)16:05:22

Maven’s resolution is really dumb

Alex Miller (Clojure team)16:05:46

it just uses the first version it finds starting from the top of the deps tree in a breadth-first way

Alex Miller (Clojure team)16:05:00

there isn’t really any version comparison or selection

ska20:05:53

Gradle uses newest version first by default, if I'm not mistaken. They also have a fail strategy which requires that you make the decision, if I understood correctly. See https://docs.gradle.org/current/userguide/customizing_dependency_resolution_behavior.html and https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html

ska21:05:57

Speaking of gradle.... this looks interesting: https://github.com/gradle-clojure/gradle-clojure 🙂