tools-deps

yuhan 2023-05-16T17:14:13.545089Z

Not sure if this is a tools.deps specific question - what happens if two different libraries declare the same namespace, is it deterministic which one gets placed first on the classpath? The library Medley recently changed its groupId from medley to dev.weavejester, and I realised after upgrading that my project is now pulling in two versions of the library, the newer 1.7.0 version (`dev.weavejester/medley`) and an older 1.0.0 version (`medley/medley`) from a transitive dependency that was previously shadowed. But the namespace medley.core hasn't changed, and :deps is an unordered map, so how can I be sure that (require 'medley.core) loads the correct jar?

yuhan 2023-05-16T17:19:51.027389Z

I tried an experiment with the root /deps.edn:

{:paths ["src"]
 :deps {lib/old {:local/root "old"}
        lib/new {:local/root "new"}}}
/old/deps.edn
{:deps {medley/medley {:mvn/version "1.0.0"}}}
/new/deps.edn
{:deps {dev.weavejester/medley {:mvn/version "1.7.0"}}}
Depending on the ordering of the lines in the root edn, clj -X:deps tree either shows the 1.0.0 version above or before the 1.7.0, but requiring the namespace always seems to load the 1.7.0 library.

2023-05-16T17:21:18.082709Z

as far as tools.deps knows, those are two different libraries

2023-05-16T17:21:58.678839Z

so it has no magic to pick the right one or anything

2023-05-16T17:22:44.228579Z

so you need to add an exclusion to the dep pulling in the old version with the old id

yuhan 2023-05-16T17:28:55.028239Z

Is this something that people have to regularly watch out for by screening their top level dependencies for 'clashing' transitive deps? I can imagine eg. something in lib/new trying to call a newer Medley function but breaking because lib/old came first on the classpath

2023-05-16T17:30:27.333109Z

it is something that comes up from time to time, more commonly with regular java deps where the same code is packaged in multiple jars

2023-05-16T17:31:07.848519Z

sometimes you run into it with libraries that have been badly packaged (made uberjars)

2023-05-16T17:32:06.922209Z

another option would be to try and upgrade the dep that is using the old medly version, it looks like medly made the change more than a year ago

2023-05-16T17:33:05.194679Z

oh misread the date, 6-7 months ago

Alex Miller (Clojure team) 2023-05-16T17:33:37.526379Z

while you should avoid dependency with overlapping namespaces (this is almost always a mistake or an error), the classpath ordering is deterministic

2023-05-16T17:34:57.073279Z

deterministic in the sense that you will always get the same order, but not in the sense that it detects the same namepsaces in different libraries and somehow does some kind of resolution of that

2023-05-16T17:35:54.204339Z

the classpath order ultimately determines which of the namespaces would get loaded when you do a require

Alex Miller (Clojure team) 2023-05-16T17:36:55.008019Z

correct, was just trying to explain why you get the same namespace loaded in the two cases above

Alex Miller (Clojure team) 2023-05-16T17:37:02.836759Z

https://clojure.org/reference/deps_and_cli#_classpath_ordering

yuhan 2023-05-16T17:37:37.387129Z

Thanks for the info! it's not an issue in this particular case but I was wondering in general, eg. with quite a few popular libraries having moved to clj-commons or changing ownership in the past, whether this is something that causes problems

2023-05-16T17:39:29.460649Z

there is a ticket to maybe catch this kind of thing https://clojure.atlassian.net/browse/TDEPS-229

yuhan 2023-05-16T17:39:52.702819Z

aha, so in my example it was only the coincidence that "d" comes before "m"

borkdude 2023-05-16T20:25:18.962409Z

> The library Medley recently changed its groupId from medley to dev.weavejester I've done this once and will not ever do it again, it causes more trouble than it's worth, unless clojars or tools.deps introduces groupid relocation (https://github.com/clojars/clojars-web/issues/801)