jvm.namespace
namespace inspection, evaluation, cleanup, and reload workflows
Inspect namespace mappings and memory, evaluate forms in controlled namespaces, and reload dependency-ordered namespace sets.
1 Overview
The namespace combines direct evaluation helpers with std.pipe tasks for listing, clearing, resetting, and reloading namespaces. Most task functions accept one namespace, a collection, or the default current namespace.
2 Walkthrough
2.1 Inspect a namespace
(require '[jvm.namespace :as namespace])
(namespace/list-publics 'jvm.namespace)
(namespace/list-interns 'jvm.namespace)
(namespace/list-imports 'jvm.namespace)
(namespace/list-aliases 'jvm.namespace)
2.2 Evaluate in context
(namespace/eval-ns 'example.scratch
'(def answer 42))
(namespace/with-ns 'example.scratch
answer)
(namespace/eval-temp-ns
'(+ 1 2 3))
2.3 Reload a dependency set
reload sorts the supplied namespaces topologically before running the reload task. Use the clear functions narrowly; reset removes namespaces under a root and is intended for controlled development workflows.
(namespace/reload
'[example.core example.api])
(namespace/loaded? 'example.core)
(namespace/list-in-memory 'example.core)
3 API
- clear
- clear-aliases
- clear-external-imports
- clear-interns
- clear-mappings
- clear-refers
- eval-ns
- eval-temp-ns
- list-aliases
- list-external-imports
- list-imports
- list-in-memory
- list-interns
- list-loaded
- list-mappings
- list-publics
- list-refers
- loaded?
- namespace-template
- ns-context
- ns-vars
- reeval
- reload
- reload-all
- reload-task
- reset
- resolve-ns
- return-keys
- unalias
- unmap
- with-ns
v 3.0
(invoke/definvoke clear
[:pipe {:template :namespace
:params {:title "CLEAR NAMESPACE ALIASES AND MAPPINGS"
:parallel true}
:main {:fn common/ns-clear}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string)) (intern tmp 'hello 1) (ns/clear [(ns-name tmp)] {:return :summary}) => map?)
v 3.0
(invoke/definvoke clear-aliases
[:pipe {:template :namespace
:params {:title "CLEAR NAMESPACE ALIASES"
:parallel true}
:main {:fn common/ns-clear-aliases}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string)) (ns/clear-aliases [(ns-name tmp)] {:return :summary}) => map?)
v 3.0
(invoke/definvoke clear-external-imports
[:pipe {:template :namespace
:params {:title "CLEAR NAMESPACE ALIASES"
:parallel true}
:main {:fn common/ns-clear-external-imports}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (import java.io.File)) (ns/clear-external-imports [(ns-name tmp)] {:return :summary}) => map?)
v 3.0
(invoke/definvoke clear-interns
[:pipe {:template :namespace
:params {:title "CLEAR NAMESPACE INTERNS"
:parallel true}
:main {:fn common/ns-clear-interns}}])
link
(with-temp-ns [tmp] (intern tmp 'hello 1) (ns/clear-interns [(ns-name tmp)] {:return :summary}) => map?)
v 3.0
(invoke/definvoke clear-mappings
[:pipe {:template :namespace
:params {:title "CLEAR NAMESPACE MAPPINGS"
:parallel true}
:main {:fn common/ns-clear-mappings}}])
link
(with-temp-ns [tmp] (intern tmp 'join (fn [xs] (apply str xs))) (ns/clear-mappings [(ns-name tmp)] {:return :summary}) => map?)
v 3.0
(invoke/definvoke clear-refers
[:pipe {:template :namespace
:params {:title "CLEAR NAMESPACE refers"
:parallel true}
:main {:fn common/ns-clear-refers}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (clojure.core/refer 'clojure.string :only '[join])) (ns/clear-refers [(ns-name tmp)] {:return :summary}) => map?)
v 3.0
(defn eval-ns
([ns forms]
(binding [*ns* (the-ns ns)]
(->> forms
(mapv (fn [form] (eval form)))
last))))
link
(require '[std.lib]) (eval-ns 'std.lib '[(long? 1)]) => true
v 3.0
(defn eval-temp-ns
([forms]
(let [sym (gensym)]
(try
(create-ns sym)
(eval-ns sym (cons '(clojure.core/refer-clojure) forms))
(finally (remove-ns sym))))))
link
(eval-temp-ns '[(def inc1 inc) (defn inc2 [x] (+ 1 x)) (-> 1 inc1 inc2)]) => 3 "All created vars will be destroyed after evaluation." (resolve 'inc1) => nil
v 3.0
(invoke/definvoke list-aliases
[:pipe {:template :namespace
:params {:title "NAMESPACE ALIASES"
:parallel true}
:main {:fn clojure.core/ns-aliases}
:item {:post return-keys}}])
link
(ns/list-aliases '[jvm.namespace]) => map?
v 3.0
(invoke/definvoke list-external-imports
[:pipe {:template :namespace
:params {:title "NAMESPACE IMPORTS"
:parallel true}
:main {:fn common/ns-list-external-imports}
:item {:post return-keys}}])
link
(ns/list-external-imports '[jvm.namespace] {:return :summary}) => map?
v 3.0
(invoke/definvoke list-imports
[:pipe {:template :namespace
:params {:title "NAMESPACE IMPORTS"}
:main {:fn clojure.core/ns-imports}
:item {:post return-keys}}])
link
(ns/list-imports '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 482} => map?
v 3.0
(invoke/definvoke list-in-memory
[:pipe {:template :namespace.memory
:params {:title "NAMESPACE MEMORY OBJECTS"
:parallel true}
:main {:fn common/raw-in-memory}}])
link
(ns/list-in-memory 'jvm.namespace) (ns/list-in-memory '[jvm.namespace] {:print {:result false :summary false} :return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :objects 306, :functions 22} => map?
v 3.0
(invoke/definvoke list-interns
[:pipe {:template :namespace
:params {:title "NAMESPACE INTERNS"
:parallel true}
:main {:fn clojure.core/ns-interns}
:item {:post return-keys}}])
link
(ns/list-interns '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 43} => map?
v 4.0
(defn list-loaded
([]
(list-loaded :all))
([inputs]
(let [nss (common/ns-list)]
(if (= :all inputs)
nss
(filter (fn [ns]
(some (fn [sym] (.startsWith (str ns)
(str sym)))
inputs))
nss)))))
link
(ns/list-loaded '[jvm.namespace]) => (contains ['jvm.namespace])
v 3.0
(invoke/definvoke list-mappings
[:pipe {:template :namespace
:params {:title "NAMESPACE MAPPINGS"
:parallel true}
:main {:fn clojure.core/ns-map}
:item {:post return-keys}}])
link
(ns/list-mappings '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 3674} => map?
v 3.0
(invoke/definvoke list-publics
[:pipe {:template :namespace
:params {:title "NAMESPACE PUBLICS"
:parallel true}
:main {:fn clojure.core/ns-publics}
:item {:post return-keys}}])
link
(ns/list-publics '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 43} => map?
v 3.0
(invoke/definvoke list-refers
[:pipe {:template :namespace
:params {:title "NAMESPACE REFERS"
:parallel true}
:main {:fn clojure.core/ns-refers}
:item {:post return-keys}}])
link
(ns/list-refers '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 3149} => map?
v 3.0
(invoke/definvoke loaded?
[:pipe {:template :namespace.count
:params {:title "NAMESPACE LOADED?"
:parallel true}
:main {:fn common/ns-loaded?}}])
link
(ns/loaded? 'jvm.namespace) => true (ns/loaded? '[jvm.namespace]) => map?
v 3.0
(defn ns-context
([] *ns-context*))
link
(ns-context) => jvm.namespace.context.NamespaceContext
v 3.0
(defn ns-vars
([ns]
(vec (sort (keys (ns-publics ns))))))
link
(ns-vars 'jvm.namespace.context) => '[*ns-context* ->NamespaceContext map->NamespaceContext ns-context ns-vars reeval resolve-ns]
v 3.0
(defn reeval
([]
(reeval (.getName *ns*)))
([ns]
(deps/dependents-refresh (ns-context) ns)))
link
(with-redefs [deps/dependents-refresh (fn [_ ns] [:refreshed ns])] (reeval 'jvm.namespace.context)) => [:refreshed 'jvm.namespace.context]
v 3.0
(defn reload
([]
(reload-task))
([inputs]
(reload-task (dependent/sort-topo inputs))))
link
(with-redefs [ns/reload-task (fn [& _] :reloaded) dependent/sort-topo identity] (ns/reload '[jvm.namespace.dependent jvm.namespace.common])) => :reloaded
v 3.0
(invoke/definvoke reload-all
[:pipe {:template :namespace
:params {:title "RELOADS NAMESPACE AND DEPENDENCIES"
:parallel true}
:main {:fn common/ns-reload-all}}])
link
(with-redefs [common/ns-reload-all (fn [ns] nil)] (ns/reload-all '[jvm.namespace.common] {:return :summary})) => map?
v 4.1
(invoke/definvoke reload-task
[:pipe {:template :namespace
:params {:title "RELOADS NAMESPACE"
:parallel false}
:main {:fn common/ns-reload}}])
link
(with-redefs [common/ns-reload (fn [ns] nil)] (ns/reload-task '[jvm.namespace.common] {:return :summary})) => map?
v 3.0
(invoke/definvoke reset
[:pipe {:template :namespace.memory
:params {:title "RESET NAMESPACE"
:parallel true
:print {:item true
:summary true}}
:main {:fn common/ns-delete}}])
link
(let [sym (symbol "jvm.namespace.reset-temp")] (create-ns sym) (ns/reset [sym] {:return :summary}) => map?)
v 3.0
(defn resolve-ns
([^clojure.lang.Symbol sym]
(let [nsp (.getNamespace sym)
nsym (or (and nsp
(symbol nsp))
sym)]
(if nsym
(f/suppress (do (require nsym) nsym))))))
link
(resolve-ns 'clojure.core) => 'clojure.core (resolve-ns 'clojure.core/some) => 'clojure.core (resolve-ns 'clojure.hello) => nil
v 3.0
(invoke/definvoke unalias
[:pipe {:template :namespace
:params {:title "UNALIAS NAMESPACE SYMBOL"
:parallel true
:print {:result false
:summary false}}
:arglists '([:args syms] [ :args syms])
:main {:fn common/ns-unalias}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'something 'clojure.string)) (ns/unalias [(ns-name tmp)] :args '[something]) => map?)
- +class-cache+
- +namespaces+
- +ns-clojure-imports+
- +rq+
- group-in-memory
- ns-clear
- ns-clear-aliases
- ns-clear-external-imports
- ns-clear-interns
- ns-clear-mappings
- ns-clear-refers
- ns-delete
- ns-in-memory
- ns-list
- ns-list-external-imports
- ns-loaded?
- ns-reload
- ns-reload-all
- ns-unalias
- ns-unmap
- raw-in-memory
+class-cache+ ^
NONE
(defonce ^java.util.concurrent.ConcurrentHashMap +class-cache+
(query/apply-element DynamicClassLoader "classCache" []))
link
+namespaces+ ^
NONE
(defonce ^java.util.concurrent.ConcurrentHashMap +namespaces+
(query/apply-element Namespace "namespaces" []))
link
+ns-clojure-imports+ ^
NONE
(def +ns-clojure-imports+
#{java.util.concurrent.Callable
clojure.lang.DynamicClassLoader
java.math.BigInteger
clojure.lang.Namespace
java.math.BigDecimal
clojure.lang.Compiler})
link
+rq+ ^
NONE
(defonce ^java.lang.ref.ReferenceQueue +rq+
(query/apply-element DynamicClassLoader "rq" []))
link
v 3.0
(defn group-in-memory
([results]
(let [results (->> results
(map #(clojure.string/split % (re-pattern "\$")))
(map rest))
anon? (fn [[call _]]
(try (re-find #"^fn__*" call)
(catch Exception ex
true)))
anons (->> results (filter anon?) count)
eval? (fn [[call _]]
(try (re-find #"^evald+" call)
(catch Exception ex
true)))
evals (->> results (filter eval?) count)
funcs (->> results
(remove eval?)
(remove anon?)
(group-by first))
fks (sort (keys funcs))]
(cond->> (keep (fn [fk]
(try
[(symbol (f/demunge fk)) (count (get funcs fk))]
(catch Throwable t)))
fks)
(pos? anons) (cons ['ANON anons])
(pos? evals) (cons ['EVAL evals])
:then (vec)))))
link
(group-in-memory ["code.manage$add$1" "code.manage$add$2" "code.manage$sub$1" "code.manage$sub$2"]) => '[[add 2] [sub 2]]
v 3.0
(defn ns-clear
([ns]
(concat (ns-clear-aliases ns)
(ns-clear-refers ns)
(ns-clear-interns ns)
(ns-clear-external-imports ns))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string) (clojure.core/refer 'clojure.string :only '[join]) (import java.io.File)) (intern tmp 'hello 1) (let [_ (doall (ns-clear tmp))] [(ns-aliases tmp) (ns-refers tmp) (ns-interns tmp) (ns-list-external-imports tmp)])) => [{} {} {} ()]
v 3.0
(defn ns-clear-aliases
([ns]
(for [alias (keys (ns-aliases ns))]
(do (clojure.core/ns-unalias ns alias)
alias))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string) (alias 'set 'clojure.set)) [(set (ns-clear-aliases tmp)) (ns-aliases tmp)]) => [#{'str 'set} {}]
v 3.0
(defn ns-clear-external-imports
([ns]
(mapv (fn [k]
(clojure.core/ns-unmap ns k)
k)
(ns-list-external-imports ns))))
link
(ns-clear-external-imports *ns*) (ns-list-external-imports *ns*) => ()
v 3.0
(defn ns-clear-interns
([ns]
(mapv (fn [k]
(clojure.core/ns-unmap ns k)
k)
(keys (ns-interns ns)))))
link
(with-temp-ns [tmp] (intern tmp 'hello 1) [(ns-clear-interns tmp) (ns-interns tmp)]) => [['hello] {}]
v 3.0
(defn ns-clear-mappings
([ns]
(mapv (fn [k]
(clojure.core/ns-unmap ns k)
k)
(keys (ns-map ns)))))
link
(with-temp-ns [tmp] (intern tmp 'join (fn [xs] (apply str xs))) [(some #{'join} (ns-clear-mappings tmp)) (contains? (ns-map tmp) 'join)]) => ['join false]
v 3.0
(defn ns-clear-refers
([ns]
(mapv (fn [k]
(clojure.core/ns-unmap ns k)
k)
(keys (ns-refers ns)))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (clojure.core/refer 'clojure.string :only '[join])) [(ns-clear-refers tmp) (ns-refers tmp)]) => [['join] {}]
ns-delete ^
[ns]
Added 3.0
clears all namespace mappings and remove namespace from clojure environment
v 3.0
(defn ns-delete
([ns]
(let [;; unload from libs
_ (dosync (alter @#'clojure.core/*loaded-libs*
disj ns))
;; clear classloader cache
results (->> (raw-in-memory ns)
(mapv (fn [k] (.remove +class-cache+ k)
k)))
;; unmap from global *namespaces
nsp (.get +namespaces+ ns)
_ (ns-clear nsp)
_ (.remove +namespaces+ ns)]
results)))
link
(let [sym (gensym "jvm.namespace.delete-test-") tmp (create-ns sym)] (intern tmp 'hello 1) (ns-delete sym) (contains? (set (ns-list)) sym)) => false
v 3.0
(defn ns-in-memory
([ns]
(->> (raw-in-memory ns)
(group-in-memory))))
link
(ns-in-memory 'code.manage) ;;[[EVAL 2]] => coll?
v 3.0
(defn ns-list-external-imports
([ns]
(->> (ns-imports *ns*)
(remove (fn [[k ^Class v]]
(or (.startsWith (.getName v) "java.lang")
(+ns-clojure-imports+ v))))
(map first))))
link
(import java.io.File) (ns-list-external-imports *ns*) => '(File)
v 3.0
(defn ns-loaded?
([ns]
(boolean (get @@#'clojure.core/*loaded-libs* ns))))
link
(ns-loaded? 'jvm.namespace.common) => true
v 3.0
(defn ns-reload
([ns]
(require ns :reload)))
link
(do (ns-reload 'jvm.namespace.common) (ns-loaded? 'jvm.namespace.common)) => true
v 3.0
(defn ns-reload-all
([ns]
(require ns :reload-all)))
link
(do (ns-reload-all 'jvm.namespace.common) (ns-loaded? 'jvm.namespace.common)) => true
v 3.0
(defn ns-unalias
([ns refer]
(cond (symbol? refer)
(do (clojure.core/ns-unalias ns refer)
refer)
(coll? refer)
(mapv #(ns-unalias ns %) refer))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string)) [(ns-unalias tmp 'str) (ns-aliases tmp)]) => ['str {}]
v 3.0
(defn ns-unmap
([ns refer]
(cond (symbol? refer)
(do (clojure.core/ns-unmap ns refer)
refer)
(coll? refer)
(mapv #(ns-unmap ns %) refer))))
link
(with-temp-ns [tmp] (intern tmp 'hello 1) [(ns-unmap tmp 'hello) (contains? (ns-map tmp) 'hello)]) => ['hello false]
- *ns-context*
- ->NamespaceContext
- NamespaceContext
- add-entry-ns
- get-deps-ns
- get-entry-ns
- list-entries-ns
- map->NamespaceContext
- ns-context
- ns-vars
- reeval
- refresh-entry-ns
- remove-entry-ns
- resolve-ns
NONE
(impl/defimpl NamespaceContext []
:suffix "-ns"
:protocols [std.protocol.deps/IDeps
protocol.deps/IDepsMutate])
link
NamespaceContext ^
NONE
(impl/defimpl NamespaceContext []
:suffix "-ns"
:protocols [std.protocol.deps/IDeps
protocol.deps/IDepsMutate])
link
NONE
(defn- add-entry-ns
([context ns _ _]
(require ns)
context))
link
NONE
(defn- get-deps-ns
([_ ns]
(->> (vals (ns-aliases ns))
(map #(.getName ^clojure.lang.Namespace %)))))
link
NONE
(impl/defimpl NamespaceContext []
:suffix "-ns"
:protocols [std.protocol.deps/IDeps
protocol.deps/IDepsMutate])
link
v 3.0
(defn ns-context
([] *ns-context*))
link
(ns-context) => jvm.namespace.context.NamespaceContext
v 3.0
(defn ns-vars
([ns]
(vec (sort (keys (ns-publics ns))))))
link
(ns-vars 'jvm.namespace.context) => '[*ns-context* ->NamespaceContext map->NamespaceContext ns-context ns-vars reeval resolve-ns]
v 3.0
(defn reeval
([]
(reeval (.getName *ns*)))
([ns]
(deps/dependents-refresh (ns-context) ns)))
link
(with-redefs [deps/dependents-refresh (fn [_ ns] [:refreshed ns])] (reeval 'jvm.namespace.context)) => [:refreshed 'jvm.namespace.context]
NONE
(defn- refresh-entry-ns
([context ns]
(common/ns-reload ns)
context))
link
NONE
(defn- remove-entry-ns
([context ns]
(common/ns-delete ns)
context))
link
v 3.0
(defn resolve-ns
([^clojure.lang.Symbol sym]
(let [nsp (.getNamespace sym)
nsym (or (and nsp
(symbol nsp))
sym)]
(if nsym
(f/suppress (do (require nsym) nsym))))))
link
(resolve-ns 'clojure.core) => 'clojure.core (resolve-ns 'clojure.core/some) => 'clojure.core (resolve-ns 'clojure.hello) => nil
v 3.0
(defn ns-all-dependents
([ns input]
(loop [acc {ns (ns-dependents ns input)}]
(let [curr (set (keys acc))
next (apply clojure.set/union (vals acc))
diff (clojure.set/difference next curr)]
(if (empty? diff)
acc
(recur (merge acc (ns-level-dependents diff input))))))))
link
(ns-all-dependents 'std.lib.sort '[hara]) => map?
v 3.0
(defn ns-dependents
([ns input]
(set (filter #(ns-has-deps % ns) (ns-select input)))))
link
(ns-dependents 'std.lib.sort '#{jvm.namespace.dependent}) => '#{jvm.namespace.dependent}
v 3.0
(defn ns-has-deps
([ns test]
(let [deps (->> (vals (ns-aliases ns))
(map #(.getName ^clojure.lang.Namespace %))
set)]
(boolean (deps test)))))
link
(ns-has-deps 'jvm.namespace.dependent 'std.lib.sort) => true
v 3.0
(defn ns-level-dependents
([nss input]
(reduce (fn [out ns]
(assoc out ns (ns-dependents ns input)))
{}
nss)))
link
(ns-level-dependents '#{std.lib.sort} '#{jvm.namespace.dependent}) => '{std.lib.sort #{jvm.namespace.dependent}}
v 3.0
(defn ns-select
([input]
(ns-select input (common/ns-list)))
([input nss]
(ut/select-inputs {:item {:list (fn [_ _] nss)}}
{}
{}
input)))
link
(ns-select [(.getName *ns*)]) => '[jvm.namespace.dependent-test]
v 3.0
(defn reeval
([]
(reeval (.getName *ns*) :all))
([input]
(reeval (.getName *ns*) input))
([ns input]
(->> (ns-all-dependents ns input)
(sort/topological-sort)
(reverse)
(mapv #(doto % (require :reload))))))
link
(->> (reeval '#{jvm.namespace.dependent}) (map str)) => ["jvm.namespace.dependent-test"]
v 4.1
(defn sort-topo
[nss]
(let [nss (set (map symbol nss))
graph (reduce (fn [acc ns]
(let [deps (->> (vals (ns-aliases ns))
(map #(.getName ^clojure.lang.Namespace %))
(filter nss)
set)]
(assoc acc ns deps)))
{}
nss)]
(sort/topological-sort graph)))
link
(require '[jvm.namespace.dependent]) (sort-topo '[jvm.namespace.dependent-test jvm.namespace.dependent]) => '[jvm.namespace.dependent jvm.namespace.dependent-test]
v 3.0
(defn eval-ns
([ns forms]
(binding [*ns* (the-ns ns)]
(->> forms
(mapv (fn [form] (eval form)))
last))))
link
(require '[std.lib]) (eval-ns 'std.lib '[(long? 1)]) => true
v 3.0
(defn eval-temp-ns
([forms]
(let [sym (gensym)]
(try
(create-ns sym)
(eval-ns sym (cons '(clojure.core/refer-clojure) forms))
(finally (remove-ns sym))))))
link
(eval-temp-ns '[(def inc1 inc) (defn inc2 [x] (+ 1 x)) (-> 1 inc1 inc2)]) => 3 "All created vars will be destroyed after evaluation." (resolve 'inc1) => nil
v 3.0
(defmacro with-ns
([ns & forms]
`(binding [*ns* (the-ns ~ns)]
~@(map (fn [form] `(eval '~form)) forms))))
link
(require '[std.lib]) (with-ns 'std.lib (long? 1)) => true
v 3.0
(defmacro with-temp-ns
([& forms]
`(try
(create-ns 'sym#)
(let [res# (with-ns 'sym#
(clojure.core/refer-clojure)
~@forms)]
res#)
(finally (remove-ns 'sym#)))))
link
(with-temp-ns (def inc1 inc) (defn inc2 [x] (+ 1 x)) (-> 1 inc1 inc2)) => 3 "All created vars will be destroyed after evaluation." (resolve 'inc1) => nil