-
Notifications
You must be signed in to change notification settings - Fork 83
/
classpath.clj
54 lines (48 loc) · 2.22 KB
/
classpath.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
(ns kaocha.classpath
"This is the add-classpath function from Pomegranate 1.0.0, extracted so we
don't need to pull in Aether."
(:refer-clojure :exclude [add-classpath])
(:require [dynapath.util :as dp]
[clojure.java.io :as io]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pomegranate
(defn ensure-compiler-loader
"Ensures the clojure.lang.Compiler/LOADER var is bound to a DynamicClassLoader,
so that we can add to Clojure's classpath dynamically."
[]
(when-not (bound? Compiler/LOADER)
(.bindRoot Compiler/LOADER (clojure.lang.DynamicClassLoader. (clojure.lang.RT/baseLoader)))))
(defn- classloader-hierarchy
"Returns a seq of classloaders, with the tip of the hierarchy first.
Uses the current thread context ClassLoader as the tip ClassLoader
if one is not provided."
([]
(ensure-compiler-loader)
(classloader-hierarchy (deref clojure.lang.Compiler/LOADER)))
([tip]
(->> tip
(iterate #(.getParent ^ClassLoader %))
(take-while boolean))))
(defn- modifiable-classloader?
"Returns true iff the given ClassLoader is of a type that satisfies
the dynapath.dynamic-classpath/DynamicClasspath protocol, and it can
be modified."
[cl]
(dp/addable-classpath? cl))
(defn add-classpath
"A corollary to the (deprecated) `add-classpath` in clojure.core. This implementation
requires a java.io.File or String path to a jar file or directory, and will attempt
to add that path to the right classloader (with the search rooted at the current
thread's context classloader)."
([jar-or-dir classloader]
(if-not (dp/add-classpath-url classloader (.toURL (.toURI (io/file jar-or-dir))))
(throw (IllegalStateException. (str classloader " is not a modifiable classloader")))))
([jar-or-dir]
(let [classloaders (classloader-hierarchy)]
(if-let [cl (filter modifiable-classloader? classloaders)]
;; Add to all classloaders that allow it. Brute force but doesn't hurt.
(run! #(add-classpath jar-or-dir %) cl)
(throw (IllegalStateException. (str "Could not find a suitable classloader to modify from "
classloaders)))))))
;; /Pomegranate
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;