Conformance: throwable chaining, URL ctor/getProtocol, ClassLoader/Thread shims

Surfaced running the DB libraries (migratus) on the jolt db library:
- java.sql.SQLException .getNextException / .getStackTrace / .printStackTrace on
  jolt throwables (conditions + ex-info) return nil/empty, so a library walking
  the exception chain doesn't crash.
- java.net.URL ctor + .getProtocol (file/http), alongside the existing url shim.
- A generic java.lang.ClassLoader: getSystemClassLoader / a thread's
  contextClassLoader resolve a named resource against the source roots (the same
  model as clojure.java.io/resource) — file: URL or nil. Thread/currentThread.
  These are generic host capabilities, not DB-specific.

The jolt-lang/db next.jdbc surface now runs migratus far enough to connect, build
the migrations table, and discover migrations; migratus's remaining dependency is
java.nio.file (FileSystems/Path/PathMatcher glob), a JVM filesystem API kept out
of core.
This commit is contained in:
Yogthos 2026-06-22 18:27:27 -04:00
parent 5c9c5ed6e1
commit 47864403e8
4 changed files with 49 additions and 0 deletions

View file

@ -110,6 +110,9 @@
{:suite "reader" :expr "(let [r (-> \"(+ 1 2) 99\" java.io.StringReader. java.io.PushbackReader.)] [(read r) (read r)])" :expected "[(+ 1 2) 99]"}
{:suite "hostctor" :expr "(String/format \"%d-%s\" 5 \"x\")" :expected "5-x"}
{:suite "hostctor" :expr "[(.format (java.text.NumberFormat/getInstance) 1234567.5) (.format (java.text.NumberFormat/getIntegerInstance) 1234567)]" :expected "[1,234,567.5 1,234,567]"}
{:suite "hostctor" :expr "[(.getProtocol (java.net.URL. \"file:/tmp/x\")) (.getFile (java.net.URL. \"http://h/p\")) (.getProtocol (java.net.URL. \"http://h/p\"))]" :expected "[file http://h/p http]"}
{:suite "hostobj" :expr "(try (throw (ex-info \"x\" {})) (catch Throwable e [(.getNextException e) (vec (.getStackTrace e))]))" :expected "[nil []]"}
{:suite "hostobj" :expr "[(some? (ClassLoader/getSystemClassLoader)) (some? (.getContextClassLoader (Thread/currentThread)))]" :expected "[true true]"}
{:suite "dotform" :expr "(.equals \"a\" \"a\")" :expected "true"}
{:suite "dotform" :expr "(.equals \"a\" \"b\")" :expected "false"}
{:suite "dotform" :expr "(. {:value 41 :describe (fn [self] (str \"v=\" (:value self)))} describe)" :expected "v=41"}