jvm.require
dependency-aware namespace requiring for development
Retry a namespace require after discovering and loading a missing namespace dependency from the compiler error chain.
1 Overview
force-require is a development helper for namespaces that fail to reload because a referenced namespace has not yet been loaded. It follows missing-namespace errors, requires the dependency, and then returns through the original stack.
2 Walkthrough
2.1 Require a namespace
(require '[jvm.require :as jvm-require])
(jvm-require/force-require
'example.application)
2.2 Use in a reload workflow
Call this helper when generating or rearranging namespaces during development. Normal application startup should generally continue to use ordinary require declarations so dependency problems remain explicit.
(doseq [namespace
'[example.model
example.service
example.application]]
(jvm-require/force-require namespace))
3 API
force-require ^
[ns] [ns stack]
Added 4.0
a more flexible require, reloading namespaces if errored
v 4.0
(defn force-require
([ns]
(force-require ns []))
([ns stack]
(let [parse-fn (fn [msg]
(if-let [ns-str (second (re-find #"namespace '(.*)' not found"
msg))]
(symbol ns-str)))
ns-dep (try
(require ns :reload)
nil
(catch Throwable t
(if-let [cause (.getCause t)]
(if-let [ns-dep (parse-fn (.getMessage cause))]
ns-dep
(throw t))
(throw t))))]
(cond ns-dep
(do (env/p :REQUIRING ns-dep)
(recur ns-dep (cons ns stack)))
(not-empty stack)
(recur (first stack) (rest stack))
:else
(env/p :DONE)))))
link
(force-require 'jvm.require) => nil