This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-10-27
Channels
- # announcements (14)
- # aws (2)
- # babashka (12)
- # beginners (23)
- # calva (71)
- # cider (37)
- # clj-kondo (47)
- # cljs-dev (3)
- # clojure (55)
- # clojure-brasil (1)
- # clojure-europe (51)
- # clojure-nl (1)
- # clojure-norway (63)
- # clojure-poland (1)
- # clojure-seattle (1)
- # clojure-uk (3)
- # clojurescript (10)
- # conjure (3)
- # cursive (23)
- # data-science (5)
- # emacs (16)
- # events (1)
- # hoplon (16)
- # hyperfiddle (19)
- # introduce-yourself (1)
- # kaocha (5)
- # nyc (1)
- # portal (31)
- # practicalli (2)
- # reitit (3)
- # releases (4)
- # sci (28)
- # slack-help (13)
- # sql (4)
- # squint (40)
- # tools-build (25)
- # tools-deps (10)
Hi! I’m looking for a bit of a sanity check. I believe the following assumptions are true:
1. When I write Number
in a Clojure REPL, “Number” refers to java.lang.Number (https://docs.oracle.com/javase/8/docs/api/java/lang/Number.html)
2. Numbers as used in clojure.core and clojure.math are all instances of java.lang.Number
3. Multimethods “know about” hierarchies when they dispatch
4. Java class hierarchies are also Clojure hierarchies.
I believe that i can therefore write a multimethod that with type
as dispatch-fn, and handle Number
in a defmethod, and my own type in a different defmethod.
Am I wrong? (I hope this question isn’t too vague to make sense)
Keep in mind if multiple methods match for a given dispatch value, you'll need to manually set which is preferred.
Hi all, has anybody ever encountered this error when compiling http-kit?
clojure -T:build uber :jar-name setup.jar :target-dir \"out/dist\"
Checking out: at 5316639d4e43a7b3ff6d48a90bbae0647e8150af
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:445).
org.httpkit.client.HttpClient
Full report at:
/tmp/clojure-7262190232603337376.edn
Execution error (ExceptionInfo) at clojure.tools.build.tasks.compile-clj/compile-clj (compile_clj.clj:114).
Clojure compilation failed, working dir preserved: /tmp/compile-clj5716707053231805684
Full report at:
/tmp/clojure-5252432327774702449.edn
make: *** [Makefile:77: out/dist/setup.jar] Error 1
it is a dependency of that project and the class https://github.com/http-kit/http-kit/blob/v2.7.0/src/org/httpkit/client.clj#L10 - Is that not the problem? I might be off
oh sorry, I'll post the full stack trace
And that is likely the problem, http-kit has java source code that needs to be compiled
ah, yeah, but this used to work before?
Did the clojure build tool change w.r.t. compiling?
I see a step in their deps.edn
https://github.com/http-kit/http-kit/blob/v2.7.0/deps.edn#L8
Ok it seems I just need to add clojure -X:deps prep
before building the uberjar...
https://clojure.org/guides/deps_and_cli#prep_libs
Thank you, you comment made me realize a few more things
yeah, it's not a rationale but another error I faced
Execution error (ExceptionInfo) at clojure.tools.deps.extensions.maven/get-artifact (maven.clj:167).
Could not transfer artifact http-kit:http-kit:jar:2.7.0 from/to clojars ( ): status code: 416, reason phrase: Range Not Satisfiable (416)
% clj -Sdeps '{:deps {http-kit/http-kit {:mvn/version "2.7.0"}}}'
Downloading: http-kit/http-kit/2.7.0/http-kit-2.7.0.pom from clojars
Downloading: http-kit/http-kit/2.7.0/http-kit-2.7.0.jar from clojars
Clojure 1.11.1
user=>
🤷$ clj -Sdeps '{:deps {http-kit/http-kit {:mvn/version "2.7.0"}}}'
Error building classpath. Could not transfer artifact http-kit:http-kit:jar:2.7.0 from/to clojars ( ): status code: 416, reason phrase: Range Not Satisfiable (416)
Very strangeSomething in your user deps.edn
perhaps? Does this work for you?
clj -Srepro -Sdeps '{:deps {http-kit/http-kit {:mvn/version "2.7.0"}}}'
Uhm, good point - tried but nope, same error
$ clj -Srepro -Sdeps '{:deps {http-kit/http-kit {:mvn/version "2.7.0"}}}'
Error building classpath. Could not transfer artifact http-kit:http-kit:jar:2.7.0 from/to clojars ( ): status code: 416, reason phrase: Range Not Satisfiable (416)
I've seen some suggestions that if you get that error you should check for a partially downloaded jar in ~/.m2 and delete it
Hey, that worked!
i have a top-level logging call in a namespace. when i call clojure -T:build uberjar
, i see that logging call twice, which tells me it's being loaded twice. is that coming from calling b/compile-clj
and then b/uber
? is it something I should be worried about otherwise?
one thing i like to do is add a form like
(require 'clojure.repl)
(clojure.repl/pst (Exception. "trace") 50)
and then you can see who is calling and under what circumstances. Other ways to do it but this does some moderate stack trace cleanup and lets me see what is going onthat's really clever
Don’t think uber should load anything
More likely getting loaded twice during compile but hard to say
i ran b/uber
from the repl and nabbed the compile script from write-compile-script!
. followed the stack traces as @U11BV7MTK suggested, and i see that at line 15, (compile 'crossbeam.routes.N)
is called which (through 15+ namespaces of requires) loads the target namespace, and then at line 106, there's (compile 'crossbeam.target-namespace)
given that lots of people use this and no one seems harmed by it lol, i'm guessing that this isn't worrisome for things like records?
and for some reason, I thought compile
was transitive and would compile everything in the require'd tree as well as the target namespace
i would only compile things once. You can end up with maddening issues like type X cannot be cast to type X
yeah, that's what i thought. i'm not sure how these two interplay, so maybe it's okay?
i'm not, this is part of`tools.build`'s uberjar
function
Are you compiling just the main ns or all nses?
(I generally recommend only compiling the main ns -- since it's transitive -- and then adding only nses you know are dynamically loaded which wouldn't be reached by transitive compilation from main)
this is our uberjar
function:
(defn uberjar
[_]
(let [basis (b/create-basis {:project "deps.edn"})]
(clean nil)
(b/copy-dir {:src-dirs ["src" "resources"]
:target-dir class-dir})
(b/compile-clj {:basis basis
:src-dirs ["src"]
:class-dir class-dir})
(b/uber {:class-dir class-dir
:uber-file uberjar-file
:main 'crossbeam.core
:basis basis
:manifest {"Add-Opens" "java.base/java.nio"}
:exclude [#"^META-INF/license/LICENSE.*"]})))
your comment and reading the tools.build code makes me wonder if we should be passing in :ns-compile
instead of :src-dirs
Yes. Specify the main ns with that 🙂
hmm that solved the double-load issue. i'll have to test the resulting jar to make sure we're not doing anything dynamic and naughty lol
(`:src-dirs` is also needed I think? ... hmm, maybe not if you specify :ns-compile
... I think I do it just by default since :src-dirs
is used for other stuff in the build pipeline and I pass options all the way through in general)
the docs say it only needs :src-dirs if there's no paths in the basis (which we are providing with our deps.edn)
Ah, yeah, that would be it...
maybe the tools.build guide should recommend :ns-compile
instead of :scr-dirs
. it looks like whoever wrote this copied the example directly and only lightly modified it lol
thanks everyone, glad to solve this
> maybe the tools.build guide should recommend :ns-compile instead of :scr-dirs. Post on http://ask.clojure.org about it 🙂
src-dirs is actually not even needed (will use :paths from basis by default)
thank you, i'll close the github issue i was in the process of writing lol
I'm also only using :ns-compile [main-ns]
by default, weird things happen with graalvm native-image if you don't. lein's behavior same: :aot [main-ns]
, never :aot :all
Yeah... "AOT ALL THE THINGS!!!" always made me nervous 🙂
I've updated the tools.build guide and tweaked the tools.build docstring for compile-clj