This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-04-28
Channels
- # announcements (2)
- # babashka (21)
- # beginners (24)
- # calva (9)
- # cider (7)
- # clj-kondo (12)
- # clojure (116)
- # clojure-europe (5)
- # clojure-korea (2)
- # clojure-norway (3)
- # clojure-poland (1)
- # clojure-spec (5)
- # clojurescript (12)
- # cursive (12)
- # datomic (8)
- # google-cloud (4)
- # honeysql (16)
- # java (18)
- # lsp (10)
- # missionary (14)
- # polylith (12)
- # re-frame (13)
- # releases (4)
- # shadow-cljs (10)
- # sql (10)
- # testify (2)
i've currently the problem that i can't build with deps.edn based project. My uberjar task doesn't compile. So it throws an error during the compile phase. The error itself doesn't say a lot sadly 😕
Execution error (ExceptionInfo) at clojure.tools.build.tasks.compile-clj/compile-clj (compile_clj.clj:114).
Does anybody know what could be the problem? Furthermore the class files are also not generated. I've added the gen-class stuff to my main namespace 😕Can you provide the command you ran, the build.clj and the full output?
build.clj
(ns build
(:require [clojure.tools.build.api :as b]))
(def version (format "1.2.%s" (b/git-count-revs nil)))
(def class-dir "target/classes")
(def uber-file (format "target/%s-%s-standalone.jar" "jobplatform" version))
;; delay to defer side effects (artifact downloads)
(def basis (delay (b/create-basis {:project "deps.edn"})))
(defn clean [_]
(b/delete {:path "target/classes"}))
(defn uber [_]
(clean nil)
(b/copy-dir {:src-dirs ["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 uber-file
:basis basis
:main 'jobplatform.core}))
The full outbut after clojure -T:build uber
* run-java-tool was invoked directly
* run-java-tool should only be used via symlinks to it
Execution error (ExceptionInfo) at clojure.tools.build.tasks.compile-clj/compile-clj (compile_clj.clj:114).
Clojure compilation failed, working dir preserved: /tmp/compile-clj11458567838255310607
Full report at:
/tmp/clojure-5265600849608910499.edn
The edn.
{:clojure.main/message
"Execution error (ExceptionInfo) at clojure.tools.build.tasks.compile-clj/compile-clj (compile_clj.clj:114).\nClojure compilation failed, working dir preserved: /tmp/compile
-clj11458567838255310607\n",
:clojure.main/triage
{:clojure.error/class clojure.lang.ExceptionInfo,
:clojure.error/line 114,
:clojure.error/cause
"Clojure compilation failed, working dir preserved: /tmp/compile-clj11458567838255310607",
:clojure.error/symbol
clojure.tools.build.tasks.compile-clj/compile-clj,
:clojure.error/source "compile_clj.clj",
:clojure.error/phase :execution},
:clojure.main/trace
{:via
[{:type clojure.lang.ExceptionInfo,
:message
"Clojure compilation failed, working dir preserved: /tmp/compile-clj11458567838255310607",
:data {},
:at
[clojure.tools.build.tasks.compile_clj$compile_clj
invokeStatic
"compile_clj.clj"
114]}],
:trace
[[clojure.tools.build.tasks.compile_clj$compile_clj
invokeStatic
"compile_clj.clj"
114]
[clojure.tools.build.tasks.compile_clj$compile_clj
invoke
"compile_clj.clj"
82]
[clojure.lang.Var invoke "Var.java" 384]
[clojure.tools.build.api$compile_clj invokeStatic "api.clj" 317]
[clojure.tools.build.api$compile_clj invoke "api.clj" 277]
[build$uber invokeStatic "build.clj" 18]
[build$uber invoke "build.clj" 14]
[clojure.lang.Var invoke "Var.java" 384]
[clojure.run.exec$exec invokeStatic "exec.clj" 89]
[clojure.run.exec$exec invoke "exec.clj" 78]
[clojure.run.exec$_main$fn__220 invoke "exec.clj" 228]
[clojure.run.exec$_main invokeStatic "exec.clj" 224]
[clojure.run.exec$_main doInvoke "exec.clj" 192]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.lang.Var applyTo "Var.java" 705]
[clojure.core$apply invokeStatic "core.clj" 667]
[clojure.main$main_opt invokeStatic "main.clj" 514]
[clojure.main$main_opt invoke "main.clj" 510]
[clojure.main$main invokeStatic "main.clj" 664]
[clojure.main$main doInvoke "main.clj" 616]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.lang.Var applyTo "Var.java" 705]
[clojure.main main "main.java" 40]],
:cause
"Clojure compilation failed, working dir preserved: /tmp/compile-clj11458567838255310607",
:data {}}}
Funny part is that there is no class files and even the copy of the resource folder isn't in the target folder 😕
with lein the uberjar build works. BUT i wanted to give that method a try cause afaik its the new official way right?
and doing a (compile 'jobplatform.core)
leads to
Syntax error macroexpanding clojure.core/ns at (jobplatform/core.clj:1:1).
No such file or directory
The very last error is probably because the classes
directory is missing.
Not the target/classes
that your build.clj
mentions, but the value of *compile-path*
, which by default is just "classes"
.
Yeah but i have no clue :/ switched to lein and everything works great :/ maybe i'm just to dumb xD
An explicit call to compile
won't work with Lein just as well, because it's not about your tools but rather about how compile
works.
Ah good to know. You know last time i was investibg into clojure like 5 or 6 years ago there was only lein :D just wanted to expand my knowledge and get back to awesome lisp development
These lines in the output seem to be crucial:
* run-java-tool was invoked directly
* run-java-tool should only be used via symlinks to it
They are not from tools.build
, they're from your Java wrapper.
And e.g. https://gitweb.gentoo.org/proj/eselect-java.git/tree/src/scripts/run-java-tool.bash.in?id=2b7d0f087f3fdec791a4667512ecfe71f64a9ffd exits with non-0 status after printing those lines.
So the issue seems to be your Java setup.
As for why it works with Lein - I don't know how it works but either it doesn't use that Java command or it uses the Java process where it was launched. Probably the former.
The way tools.build
determines the Java command to use if you don't explicitly specify :java-cmd
for compile-clj
is, in order:
1. The JAVA_CMD
env var
2. java
in PATH
3. bin/java
under JAVA_HOME
That should give you enough info to be able to fix the problem.Btw whats the current state of the art build wise still leiningen or is it allready boot or deps.edn
What's in /tmp/clojure-5265600849608910499.edn ?
I don't think the java thing is an issue or it wouldn't have run at all
The EDN was posted above.
Pretty sure it is the issue since the run-java-tool
wrapper uses exit 1
.
Seems the main process was run with one version of Java but compile-clj
tried to use that wrapper.
I guess, can also set :java-cmd
on the compile-clj task to a specific path to the java executable if needed
ok after setting JAVA_CMD or JAVA_HOME the build is complaining that it can't find clojure.main
can you share the actual output
❯ JAVA_HOME=/opt/openjdk-bin-17.0.10_p7/bin/javac JAVA_CMD=/usr/bin/java clojure -T:build uber
Error: Could not find or load main class clojure.main
Caused by: java.lang.ClassNotFoundException: clojure.main
Execution error (ExceptionInfo) at clojure.tools.build.tasks.compile-clj/compile-clj (compile_clj.clj:114).
Clojure compilation failed, working dir preserved: /tmp/compile-clj3444501778209445454
Full report at:
/tmp/clojure-15222711653787284576.edn
{:clojure.main/message
"Execution error (ExceptionInfo) at clojure.tools.build.tasks.compile-clj/compile-clj (compile_clj.clj:114).\nClojure compilation failed, working dir preserved: /tmp/compile-clj3444501778209445454\n",
:clojure.main/triage
{:clojure.error/class clojure.lang.ExceptionInfo,
:clojure.error/line 114,
:clojure.error/cause
"Clojure compilation failed, working dir preserved: /tmp/compile-clj3444501778209445454",
:clojure.error/symbol
clojure.tools.build.tasks.compile-clj/compile-clj,
:clojure.error/source "compile_clj.clj",
:clojure.error/phase :execution},
:clojure.main/trace
{:via
[{:type clojure.lang.ExceptionInfo,
:message
"Clojure compilation failed, working dir preserved: /tmp/compile-clj3444501778209445454",
:data {},
:at
[clojure.tools.build.tasks.compile_clj$compile_clj
invokeStatic
"compile_clj.clj"
114]}],
:trace
[[clojure.tools.build.tasks.compile_clj$compile_clj
invokeStatic
"compile_clj.clj"
114]
[clojure.tools.build.tasks.compile_clj$compile_clj
invoke
"compile_clj.clj"
82]
[clojure.lang.Var invoke "Var.java" 384]
[clojure.tools.build.api$compile_clj invokeStatic "api.clj" 317]
[clojure.tools.build.api$compile_clj invoke "api.clj" 277]
[build$uber invokeStatic "build.clj" 18]
[build$uber invoke "build.clj" 14]
[clojure.lang.Var invoke "Var.java" 384]
[clojure.run.exec$exec invokeStatic "exec.clj" 89]
[clojure.run.exec$exec invoke "exec.clj" 78]
[clojure.run.exec$_main$fn__220 invoke "exec.clj" 228]
[clojure.run.exec$_main invokeStatic "exec.clj" 224]
[clojure.run.exec$_main doInvoke "exec.clj" 192]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.lang.Var applyTo "Var.java" 705]
[clojure.core$apply invokeStatic "core.clj" 667]
[clojure.main$main_opt invokeStatic "main.clj" 514]
[clojure.main$main_opt invoke "main.clj" 510]
[clojure.main$main invokeStatic "main.clj" 664]
[clojure.main$main doInvoke "main.clj" 616]
[clojure.lang.RestFn applyTo "RestFn.java" 137]
[clojure.lang.Var applyTo "Var.java" 705]
[clojure.main main "main.java" 40]],
:cause
"Clojure compilation failed, working dir preserved: /tmp/compile-clj3444501778209445454",
:data {}}}
can you post the /tmp/compile-clj3444501778209445454/compile.args file
/usr/bin/java -cp /tmp/compile-clj3444501778209445454/compile-clj:target/classes clojure.main /tmp/compile-clj3444501778209445454/compile.clj
that is the actual command being run during the compile, you should be able to run it from your project directory at the terminal, not sure you will see anything different, but you could try that
the error makes it seem like clojure is not on the classpath, but I'm not sure how that would be happening. I guess I'm assuming your deps.edn is a typical deps.edn file
{:paths ["src"]
:deps
{ compojure/compojure { :mvn/version "1.7.1"}
ring/ring-core { :mvn/version "1.12.1"}
ring/ring-devel { :mvn/version "1.12.1"}
com.github.seancorfield/next.jdbc {:mvn/version "1.3.925"}
com.h2database/h2 {:mvn/version "2.2.224"}
hiccup/hiccup {:mvn/version "2.0.0-RC3"}
org.clojure/data.zip {:mvn/version "1.1.0"}
ring/ring-jetty-adapter { :mvn/version "1.8.2"}}
:aliases
{;; Run with clj -T:build function-in-build
:build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.0" :git/sha "3a2c484"}}
:ns-default build}}}
https://clojure.org/guides/tools_build, but seems like you are mostly doing that
I don't see any reason to believe that's an issue
can you run the command above? or push up this project to git or something
i guess i can upload the hello world thing i did besides that that also doesn't work maybe my java installation doesn't work
You have:
> JAVA_HOME=/opt/openjdk-bin-17.0.10_p7/bin/javac JAVA_CMD=/usr/bin/java ...
but JAVA_HOME
should be a folder and, generally, JAVA_CMD
is going to identify the java
command within that specific version install so I'd expect either:
> JAVA_HOME=/opt/openjdk-bin-17.0.10_p7 ...
or
> JAVA_CMD=/opt/openjdk-bin-17.0.10_p7/bin/java ...
(note: /bin/java
not /bin/javac
for the CMD
)i have tried it either way and you are right they java_home javac path was wrong in my paste but i undid that and came to the same clojure.main class not found exception sadly 😕 i don't get it why lein works and deps.edn not 😕 i want to use deps.edn 😄 somehow.
A good opportunity to learn the basics of tracing tools, if you're up for it. :)
I'd look any sort of top
(`top`, htop
, btop
, etc.) what exactly lein
launches (easier if you put (Thread/sleep 1000000)
somewhere). Or use strace
with a filter for any syscalls that launch subprocesses.
Learning how to view some the env of some process is also useful.
All that is pretty basic stuff, easy to look up, even easier with LLMs.
And in my case, it's enough to figure out what the hell is going on in around 80% of the cases.
My guess is that lein
uses the same exact executable with maybe the same exact env that was used to launch its main process.
I’ll ask again - can you run the command in compile.args? If that doesn’t work, what do you get?
Error: Could not find or load main class clojure.main
Caused by: java.lang.ClassNotFoundException: clojure.main
So somehow the classpath does not include your deps
Don't you need to deref your basis? I see a similar error when using delay without the deref.
Yes! Thank you
That’s probably something I can add a check for
@basis
instead of basis
-- look closely at your build.clj
and at the guide on http://clojure.org that was linked above.
@
= deref
-- since you have (delay ..)
in your basis
def
, you need to deref
the delay
in order to get the underlying value.
so to sum up. On gentoo or any distro that uses run-java-tool you have to set the java runtime as env either JAVA_HOME
or in my case JAVA_CMD
and as @U04V70XH6 mentioned you have to use @basis in the edn file. I was confused cause on the internet there was plenty of other stuff too. So add your JAVA_CMD
and follow the official docs guys. Thanks again
> On gentoo or any distro that uses run-java-tool you have to set the java runtime as env either JAVA_HOME
or in my case JAVA_CMD
This doesn't sound right, given how tools.build
searches for Java.
Are you sure your env
in a new shell doesn't include any JAVA_
variables?
You may see examples of build.clj
that do not have the delay
on computing the basis
-- in which case those wouldn't deref
it at use.
Personally, I tend to create the basis inside a function: https://github.com/seancorfield/honeysql/blob/develop/build.clj#L86-L96 and just call that where I specifically need options with a :basis
key.
i'll check one minute btw thank you too @U2FRKM4TW and @U064X3EF3
declare -x JAVAC="/home/metti/.gentoo/java-config-2/current-user-vm/bin/javac" thats what there is only
and what the clojure script does is it uses type -p java
which on gentoo gives you the /usr/bin/java
which is basically a symlink to run-java-tool
> which on gentoo gives you the /usr/bin/java
which is basically a symlink to run-java-tool
That's perfectly fine because run-java-tool
specifically asks to be run via a symlink. But somehow it's being used directly.
@U2FRKM4TW thats right thats strange
You can also try running your build process in a way that results in that run-java-tool
error with (into {} (filter #(clojure.string/starts-with? (key %) "JAVA")) (System/getenv))
printed somewhere inside the script and see what it outputs. Just in case.
{JAVAC /home/metti/.gentoo/java-config-2/current-user-vm/bin/javac}
Thats all there is than 😕 if i run itAhh, I see. @U064X3EF3 Caused by https://github.com/clojure/tools.build/blob/181ef9c90fd82014e4e44e711e3aec9baefeb3d7/src/main/clojure/clojure/tools/build/tasks/process.clj#L108`.getCanonicalPath` that resolves symlinks.
whats strange is that doesn't the emacs cider mode use clojure to initialize the repl? Cause there everything just works fine.
ah ok i see guess its due to the compilation of the code? that you need the right executable than?
No, it's just a combination of that wrapper on Gentoo being very strict with how it's called (for seemingly a good reason - the existence of the wrapper should be left as an implementation detail, nobody should rely on the wrapper directly), and tools.build
using .getCanonicalPath
, nothing more to that particular error.
Am I crazy, or did the reader used to add line and column metadata to all metadata-having forms? I'm looking at the code now and only see that metadata being added to lists...
don't think anything has changed for that
There's a chance you're thinking about some tool that does that, e.g. Clerk, like described here: https://clojurians.slack.com/archives/C66EM8D5H/p1713893176618759
@U053S2W0V I have vague memories of being confused by this a while ago... You experiencing this?:
$ clj
Clojure 1.11.3
user=> (meta '(1 2 3))
{:line 1, :column 8}
Some elaboration https://github.com/clojure/tools.reader?tab=readme-ov-file#rationale:
> Moreover, by using reader types from clojure.tools.reader.reader-types
, if using an IndexingReader, column info is available and both line and column metadata is attached not only to lists, but to symbols, vectors and maps too, when additional debugging info is needed (note that the edn reader doesn't add any line/column metadata at all).user=> (map (juxt identity meta) (tree-seq sequential? seq '(1 [x (y)])))
([(1 [x (y)]) {:line 1, :column 71}]
[1 nil]
[[x (y)] nil]
[x nil]
[(y) {:line 1, :column 77}]
[y nil])
was expecting to see meta on anything that satisfies IMeta, but was hoping to see it on the symbols at least
I agree this would be useful. There's an Ask about this: https://ask.clojure.org/index.php/13314/location-data-on-all-iobj
The changes in Clojure 1.12 don't affect the way protocols are extended to primitive types such as byte arrays, right? That is, I will still have to do the Class/forName
thing:
(extend-protocol Writable
(Class/forName "[B")
(write [this ^OutputStream out]
...))
Oh, it seems it does and I can use byte/1
instead, and the ordering no longer matters. 🙌
λ clj -Srepro -M -r
Clojure 1.11.1
user=> (defprotocol P (m [this]))
P
user=> (extend-protocol P (Class/forName "[B") (m [_] :b) String (m [_] :s))
nil
user=> (extend-protocol P String (m [_] :s) (Class/forName "[B") (m [_] :b))
Syntax error (IllegalArgumentException) compiling at (REPL:1:1).
Don't know how to create ISeq from: java.lang.Character
Clojure 1.12.0-alpha10
user=> (defprotocol P (m [this]))
P
user=> (extend-protocol P String (m [_] :s) byte/1 (m [_] :b))
nil
user=>
Well this is awkward (started in this https://ask.clojure.org/index.php/13854/inst-changes-old-dates-in-clojure-1-12-alpha10):
Clojure 1.12.0-alpha10
user=> (.getTime #inst "1582-02-24")
-12237696000000
user=> (let [d #inst "1582-02-24"] (.getTime d))
-12237696000000
user=> (do (def d #inst "1582-02-24") (.getTime d))
-12238560000000
In the top form the string is read as a date, then converted to a different string (the bottom arrow), then read again.
Right, and that second printing is different in 1.12.0 from the original input due to how printing of dates is implemented.
Is it just a Clojure printing thing or does Java do something weird too?
I've never tried playing with dates around Gregorian calendar inception 😅
FWIW in Java I get (almost) the last result (different because of time zone I assume)
I don't know what's up with the first two numbers
the only thing that has changed is printing, but we'll take a look
Forgot to add - Java 21.0.3. @U06PNK4HG On 1.12.0-alpha10?
So I assume you also get this with all combinations?
user=> #inst "1582-02-24"
#inst "1582-02-24T00:00:00.000-00:00"
whereas I get this:
Clojure 1.12.0-alpha10
user=> #inst "1582-02-24"
#inst "1582-03-06T00:00:00.000-00:00"
Clojure 1.11.3
user=> #inst "1582-02-24"
#inst "1582-02-24T00:00:00.000-00:00"
Weird. Here's a full unabridged reproduction.
Does it also output 1582-02-24
for you? (Should be fine to use docker
instead of podman
if that's what you usually use).
$ podman run -it --rm eclipse-temurin:21-jdk bash
root@b88b07e2634a:/# curl -L -O
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 1864 100 1864 0 0 1197 0 0:00:01 0:00:01 --:--:-- 0
root@b88b07e2634a:/# chmod +x linux-install.sh
root@b88b07e2634a:/# ./linux-install.sh
Downloading and expanding tar
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 14.4M 100 14.4M 0 0 4534k 0 0:00:03 0:00:03 --:--:-- 7157k
Installing libs into /usr/local/lib/clojure
Installing clojure and clj into /usr/local/bin
Installing man pages into /usr/local/share/man/man1
Removing download
Use clj -h for help.
root@b88b07e2634a:/# clojure -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.12.0-alpha10"}}}' -M -r
Downloading: org/clojure/clojure/1.12.0-alpha10/clojure-1.12.0-alpha10.pom from central
Downloading: org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.pom from central
Downloading: org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.pom from central
Downloading: org/clojure/pom.contrib/1.1.0/pom.contrib-1.1.0.pom from central
Downloading: org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar from central
Downloading: org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar from central
Downloading: org/clojure/clojure/1.12.0-alpha10/clojure-1.12.0-alpha10.jar from central
Clojure 1.12.0-alpha10
user=> #inst "1582-02-24"
#inst "1582-03-06T00:00:00.000-00:00"
user=>
Still weird that you got a different result outside of Docker. Just in case, not from Docker:
$ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.12.0-alpha10"}}}' -M -r
Clojure 1.12.0-alpha10
user=> #inst "1582-02-24"
#inst "1582-03-06T00:00:00.000-00:00"
user=> (str (java.util.Calendar/getInstance))
"java.util.GregorianCalendar[time=1714374246288,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=\"Asia/Nicosia\",offset=7200000,dstSavings=3600000,useDaylight=true,transitions=128,lastRule=java.util.SimpleTimeZone[id=Asia/Nicosia,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2024,MONTH=3,WEEK_OF_YEAR=18,WEEK_OF_MONTH=5,DAY_OF_MONTH=29,DAY_OF_YEAR=120,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=5,AM_PM=0,HOUR=10,HOUR_OF_DAY=10,MINUTE=4,SECOND=6,MILLISECOND=288,ZONE_OFFSET=7200000,DST_OFFSET=3600000]"
I found the culprit. If I use rebel-readline, it always renders as 1582-02-24...
. But without it, I get the same behavior as you
It's a bit deeper than printing. Or it is about printing, but in the end it influences the #=()
expression.
user=> (decompile #inst "1582-02-24")
...
public static void __init0() {
const__0 = RT.readString("#inst \"1582-03-26T00:00:00.000-00:00\"");
}
...
Funny that if you try to decompile that, the read date drifts even further:
(decompile (.getTime #inst "1582-03-26T00:00:00.000-00:00"))
...
public static void __init0() {
const__0 = RT.readString("#inst \"1582-04-25T00:00:00.000-00:00\"");
}
...
Seems like Clojure is doing a Julian/Gregorian conversion or something in the print-read roundtripThis is the change that causes differences in printing, but you probably know that: https://clojure.atlassian.net/browse/CLJ-2803 https://github.com/clojure/clojure/commit/213c50e7a34a27901b6db835b87f840a8b2a36ee
Huh...
jdk21 👆:skin-tone-2: