If someone is up for some bytecode nerdery: reify in babashka is implemented using some pre-generated bytecode for each interface that is reify-able.
That's done using the insn library in this https://github.com/babashka/babashka/blob/master/impl-java/build.clj and https://github.com/babashka/babashka/blob/master/impl-java/build/reify2.clj implementation.
Currently it supports all vetted/curated interfaces. But when adding java.time.temporal.TemporalField the limitation is revealed that it doesn't support methods that return longs.
Issue here: https://github.com/babashka/babashka/issues/1882
It's been a while since I looked at the insn code. For anyone who is really interested in bytecode with insn, this might be a fun issue to solve.
LLM use is fine as long as you can fully explain the changes to me with words you understand yourself.
Am I missing something big or doesn't it just come down to extending the dispatches that already happen for int? I'll be home and testing any moment.
that's certainly part of it
if I remember correctly, it's also something with long being 2 things long so you have to adjust some index or so
you can run clj -T:build install to install the adjustment. and then run clj -M:babashka/dev run bb from source with the new lib.
My :babashka/dev alias is situated in my .clojure/deps.edn as:
{:aliases {:babashka/dev {:paths []
:deps {babashka/babashka {:local/root "/Users/borkdude/dev/babashka"}}
:main-opts ["-m" "babashka.main"]
}
where /Users/borkdude/dev/babashka is my local checkout of bb + git submoduleshere's info on how to clone the repo: https://github.com/babashka/babashka/blob/master/doc/build.md#clone-repository
the clj -T:build install should be run in the java-impl dir
thanks
thank you for taking a peek
I'm coming home to this lol: https://www.githubstatus.com/. I wonder if it's related to the Cloudflare outage or if it's its own thing.
lol o no
oh well, looks like it's working now
it seems like I got it working
wow nice!
are there more tests I can run to be sure? Also, fwiw I added the two required classes for the issue, should I push the PR with them as well or just the changes to the reify2 file?
I don't know exactly what you mean, but just make the PR and then we can take it further
ok nice
alright, I was pushing my own thing, but I saw that you happen to have a similar branch which more or less does the same thing as mine, so I'm definitely missing something...
I'll make the PR against that branch anyway
Oh please ignore most of what I had in that branch, t least the build.clj file is incorrect. You can borrow from it for your own PR.
@doppiaelle1999 I see you opened a PR and then closed it. Are you going to open a new one with your stuff?
It's fine to PR it against my branch if you want to. As long as it works, I'm happy :)
alright, I'll PR against master with a comment showcasing a generated class
thank you for your persistence :)
done
thanks!
I have pulled and pushed your branch now as EvenMoreIrrelevance-master
and added a test:
(deftest reify-temporal-field-test
(bb nil "(def field
(reify
TemporalField
(rangeRefinedBy [_ _temporal] (ValueRange/of 0 999))
(getFrom [this temporal] 1)
(adjustInto [this temporal value] temporal)))
(prn (.rangeRefinedBy field nil)
(.getFrom field nil)
(.adjustInto field (Instant/now) 1))"))
After installing the lib with clj -T:build install and then running the test with:
I'm seeing this:
$ lein do clean, test :only babashka.reify-test/reify-temporal-field-test
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See for further details.
Syntax error (VerifyError) compiling new at (babashka/impl/reify2.clj:99:15).
Bad local variable type
Exception Details:
Location:
babashka/impl/java/time/temporal/TemporalField.adjustInto(Ljava/time/temporal/Temporal;J)Ljava/time/temporal/Temporal; @23: lload_2
Reason:
Type top (current frame, locals[2]) is not assignable to long
Current Frame:
bci: @23
flags: { }
locals: { 'babashka/impl/java/time/temporal/TemporalField', 'java/time/temporal/Temporal', top, 'clojure/lang/IFn' }
stack: { 'clojure/lang/IFn', 'babashka/impl/java/time/temporal/TemporalField', 'java/time/temporal/Temporal' }
Bytecode:
0000000: 2ab4 005e b200 48b9 0073 0200 c000 754e
0000010: 2dc6 0013 2d2a 2b20 b800 adb9 00b0 0400
0000020: c000 b2b0 bb00 7c59 12b4 b700 81bf
Stackmap Table:
full_frame(@36,{Object[#2],Object[#178],Top,Object[#117]},{})
Full report at:
/var/folders/j9/xmjlcym958b1fr0npsp9msvh0000gn/T/clojure-2143826522799449024.edn
Subprocess failed (exit code: 1)
let me see
it doesn't even relate to the test, it manifests itself by just starting bb
strange, I had no issues
I added java.time.temporal.TemporalField to the interfaces
in babashka.impl.reify2.interfaces
Maybe relevant, not sure if all JVMs verify the bytecode
$ java -version
java version "25" 2025-09-16 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 25+37.1 (build 25+37-LTS-jvmci-b01)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 25+37.1 (build 25+37-LTS-jvmci-b01, mixed mode, sharing)I had that running yesterday... let me check a thing
maybe it's just junk in my target folder, let me test again
ok the issue seems to be gone...
no idea what it was
builds just fine here btw
ok great, just a hiccup then :) I'll finish the test by fully qualifying stuff
btw I get this by setting method-slot to (count slots) (i.e. the logic before accounting for the wide longs), and loading (gen-reified TemporalField):
Exception Details:
Location:
babashka/impl/java/time/temporal/TemporalField.adjustInto(Ljava/time/temporal/Temporal;J)Ljava/time/temporal/Temporal; @23: lload_2
Reason:
Type top (current frame, locals[2]) is not assignable to long
Current Frame:
bci: @23
flags: { }
locals: { 'babashka/impl/java/time/temporal/TemporalField', 'java/time/temporal/Temporal', top, 'clojure/lang/IFn' }
stack: { 'clojure/lang/IFn', 'babashka/impl/java/time/temporal/TemporalField', 'java/time/temporal/Temporal' }
Bytecode:
0000000: 2ab4 005e b200 48b9 0073 0200 c000 754e
0000010: 2dc6 0013 2d2a 2b20 b800 adb9 00b0 0400
0000020: c000 b2b0 bb00 7c59 12b4 b700 81bf
Stackmap Table:
full_frame(@36,{Object[#2],Object[#178],Top,Object[#117]},{})
looks like the same exact error to mecool, now got this test working:
(deftest reify-temporal-field-test
(let [s (bb nil "(def field
(reify
java.time.temporal.TemporalField
(rangeRefinedBy [_ _temporal]
(java.time.temporal.ValueRange/of 0 999))
(getFrom [_ _temporal] 1337)
(adjustInto [_ temporal value] temporal)))
(prn (pr-str (.rangeRefinedBy field nil)
(.getFrom field nil)
(.adjustInto field (java.time.Instant/now) 1)))")]
(is (str/includes? s "0 - 999"))
(is (str/includes? s "1337"))
(is (str/includes? s "java.time.Instant"))))now pushed impl.java 0.1.11 to clojars and bumped it in bb. CI running here: https://github.com/babashka/babashka/tree/EvenMoreIrrelevance-master
looks like the test passed! === reify-temporal-field-test
I'm going to study your solution a bit more and then I'll merge it. thanks a ton, this saved me a lot of time
@doppiaelle1999 merged to master. thanks a bunch!