babashka

2026-05-02T10:16:27.295249Z

Hi, what is the recommended way to catch JSON parse errors when using Babashka? I tried (catch JsonParseException _ ...) but trying to import that class throws an exception:

> (import '[com.fasterxml.jackson.core JsonParseException])
java.lang.Exception: Unable to resolve classname: com.fasterxml.jackson.core.JsonParseException
Am I doing something silly? Of course I could just catch Exception but I'd like to be more specific.

exitsandman 2026-05-02T10:26:02.812699Z

A possible workaround is:

(def -json-parse-ex (Class/forName "com.fasterxml.jackson.core.JsonParseException"))

(try (json/decode "not json") (catch Exception e (instance? -json-parse-ex e)))

πŸ‘ 1
2026-05-02T10:28:17.848139Z

Thank you, I'll try that.

teodorlu 2026-05-02T12:33:20.510419Z

The error you pasted says that the Jackson you tried importing wasn't foundβ€”not exactly a parse error.

2026-05-02T12:35:32.245139Z

Yes, I might not have explained myself very well, but the work-around suggested by @doppiaelle1999 works for me. I wanted to do something like this:

(try
    (json/parse-string s)
    (catch JsonParseException _ nil))

2026-05-02T12:35:47.089479Z

...which works in Clojure, but in Babashka I was not able to import that Java exception class.

teodorlu 2026-05-02T12:50:20.083439Z

Got it! Babashka only has certain java classes available, and can't load new java classes at runtime.

πŸ‘ 1
teodorlu 2026-05-02T13:01:34.638069Z

A quick test, 1. I can get com.fasterxml.jackson.core.JsonParseException listed as an ancestor class of the exception thrown when I give cheshire.core/parse-string invalid input, 2. … but I can't import that class. So, Cheshire is included with Babashka, but the Jackson classes aren't included in https://github.com/babashka/babashka/blob/7f280ef7b66d12fa1640ec98f66d73927d382f2e/src/babashka/impl/classes.clj.

2026-05-02T13:06:40.274089Z

Yes, that's the problem I ran into. But using Class/forName and asking instance? as suggested by @doppiaelle1999 is a good-enough solution for me right now.

πŸ‘ 1
2026-05-02T13:15:12.318099Z

@teodorlu thank you for the pointer to impl/classes.clj, that might come in handy again!

πŸ™Œ 1
Daniel Slutsky 2026-05-02T18:44:16.894599Z

https://clojurians.slack.com/archives/C8NUSGWG6/p1777747432504649

πŸŽ‰ 4
2026-05-02T18:49:35.878359Z

I was trying to get /proc/meminfo with slurp to check memory stats, but I'm getting this error:

user=> (slurp "/proc/meminfo")
java.io.IOException: Invalid argument [at <repl>:1:1]
files in less protected areas load fine:
user=> (slurp "/tmp/test.txt")
"test\n"
I assume it's a permission issue? but the error wasn't what I'd expect in that case

πŸ€” 1
2026-05-07T18:29:22.325869Z

thanks guys, fs/read-all-lines does seem cleaner, I'll probably switch to that.

Bob B 2026-05-02T19:41:31.937239Z

A very superficial answer would be that bb ostensibly uses clojure's slurp, and so that would raise the question of whether clojure behaves the same way, and (at least on my machine), it does. So, this could be described as bb behaving the same as clojure, which is generally kind of the goal. I can read the file with jshell (and cat), though, so I don't think it's strictly a permissions issue - there might be more digging to do, but I wonder if it might have to do with the file being in the /proc fs.

lread 2026-05-02T19:41:46.838539Z

This seems to work:

(fs/read-all-lines "/proc/meminfo")

❀️ 1
Bob B 2026-05-02T19:42:51.703979Z

Indeed, a google search turns up this quite telling comment: <https://clojuredocs.org/clojure.core/slurp#example-542692d5c026201cdc327086>

;; On Linux, some JVMs have a bug where they cannot read a file in the /proc
;; filesystem as a buffered stream or reader.  A workaround to this JVM issue
;; is to open such a file as unbuffered:
(slurp (java.io.FileReader. "/proc/cpuinfo"))

πŸ‘ 1
seancorfield 2026-05-02T19:44:03.159909Z

Because slurp uses a buffered read, it ends up calling available() on the file (to see how many bytes can be read) and that can't work on virtual files like this.

seancorfield 2026-05-02T19:46:36.305199Z

(or at least slurp uses a BufferedInputStream if you give it a string and coerces it to a reader that way)

seancorfield 2026-05-02T19:47:44.697359Z

(slurp (io/reader "/proc/meminfo")) doesn't work either (because it creates a BufferedReader). Interesting edge case.

2026-05-02T22:43:46.469649Z

I ended up doing:

(:out (babashka.process/shell {:out :string} "cat" "/proc/meminfo"))
not sure which option is most reliable

borkdude 2026-05-04T08:55:46.721709Z

@lee's suggestion seems to be less involved?

Crispin 2026-05-04T11:55:36.956669Z

also doesn't need to call out to an external binary