This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-05-16
Channels
- # announcements (1)
- # babashka (13)
- # beginners (33)
- # calva (26)
- # cherry (33)
- # clerk (5)
- # clj-kondo (3)
- # clojure (40)
- # clojure-europe (24)
- # clojure-finland (2)
- # clojure-norway (29)
- # clojurescript (18)
- # cursive (2)
- # datomic (6)
- # docker (11)
- # emacs (12)
- # events (1)
- # fulcro (71)
- # graalvm (8)
- # hyperfiddle (2)
- # lsp (23)
- # meander (5)
- # off-topic (36)
- # polylith (4)
- # re-frame (6)
- # reitit (13)
- # shadow-cljs (87)
- # spacemacs (1)
- # tools-deps (19)
- # vim (5)
- # xtdb (57)
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?
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.so you need to add an exclusion to the dep pulling in the old version with the old id
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
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
sometimes you run into it with libraries that have been badly packaged (made uberjars)
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
while you should avoid dependency with overlapping namespaces (this is almost always a mistake or an error), the classpath ordering is deterministic
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
the classpath order ultimately determines which of the namespaces would get loaded when you do a require
correct, was just trying to explain why you get the same namespace loaded in the two cases above
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
there is a ticket to maybe catch this kind of thing https://clojure.atlassian.net/browse/TDEPS-229
> 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)