Permalink
Browse files

Use dynapath for manipulating the effective classpath

This removes the URLClasspath protocol, and delegates that responsibility
to dynapath.

This change breaks backwards compatibility for any project that
used/implemented URLClasspath.
  • Loading branch information...
1 parent 7ffee5b commit f70d38bba645ec34ccfea247f6bdd0cc6ebdb8c5 @tobias tobias committed Oct 3, 2012
Showing with 16 additions and 37 deletions.
  1. +6 −0 pom.xml
  2. +10 −37 src/main/clojure/cemerick/pomegranate.clj
View
@@ -34,6 +34,7 @@
<aetherVersion>1.13.1</aetherVersion>
<mavenVersion>3.0.4</mavenVersion>
<wagonVersion>2.2</wagonVersion>
+ <dynapathVersion>0.1.0</dynapathVersion>
</properties>
<dependencies>
@@ -67,6 +68,11 @@
<artifactId>maven-aether-provider</artifactId>
<version>${mavenVersion}</version>
</dependency>
+ <dependency>
+ <groupId>dynapath</groupId>
+ <artifactId>dynapath</artifactId>
+ <version>${dynapathVersion}</version>
+ </dependency>
<!-- wagons for dependency resolution -->
<dependency>
@@ -2,7 +2,8 @@
(:import (clojure.lang DynamicClassLoader)
(java.net URL URLClassLoader))
(:require [clojure.java.io :as io]
- [cemerick.pomegranate.aether :as aether])
+ [cemerick.pomegranate.aether :as aether]
+ [dynapath.core :as dp])
(:refer-clojure :exclude (add-classpath)))
;; call-method pulled from clojure.contrib.reflect, (c) 2010 Stuart Halloway & Contributors
@@ -21,36 +22,6 @@
(doto (.setAccessible true))
(.invoke obj (into-array Object args))))
-(defprotocol URLClasspath
- "Ability to dynamically add urls to classloaders.
-
-This protocol is an implementation detail. Use
-`modifiable-classloader?` and `add-classpath` or `add-dependencies`
-unless you are extending a type to this protocol."
- (^{:private true} can-modify? [this] "Returns true if the given classloader can be modified.")
- (^{:private true} add-url [this url] "add the url to the classpath"))
-
-(extend-type DynamicClassLoader
- URLClasspath
- (can-modify? [this] true)
- (add-url [this url] (.addURL this url)))
-
-(def ^:private url-classloader-base
- {:can-modify? (constantly true)
- :add-url (fn [this url]
- (call-method URLClassLoader 'addURL [URL] this url))})
-
-(extend URLClassLoader URLClasspath url-classloader-base)
-
-(defmacro when-resolves
- [sym & body]
- (when (resolve sym) `(do ~@body)))
-
-(when-resolves sun.misc.Launcher
- (extend sun.misc.Launcher$ExtClassLoader URLClasspath
- (assoc url-classloader-base
- :can-modify? (constantly false))))
-
(defn classloader-hierarchy
"Returns a seq of classloaders, with the tip of the hierarchy first.
Uses (clojure.lang.RT/baseLoader) -- which by default will be the
@@ -64,23 +35,25 @@ unless you are extending a type to this protocol."
(defn modifiable-classloader?
"Returns true iff the given ClassLoader is of a type that satisfies
- the URLClasspath protocol, and it can be modified."
+ the dynapath.core/DynamicClasspath protocol, and it can be modified."
[cl]
- (and (satisfies? URLClasspath cl)
- (can-modify? 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]
- (add-url classloader (.toURL (io/file jar-or-dir))))
+ (if (modifiable-classloader? classloader)
+ (dp/add-classpath-url classloader (.toURL (io/file jar-or-dir)))
+ (throw (IllegalStateException. (str classloader " is not a modifiable classloader")))))
([jar-or-dir]
(let [classloaders (classloader-hierarchy)]
(if-let [cl (last (filter modifiable-classloader? classloaders))]
(add-classpath jar-or-dir cl)
- (throw (IllegalStateException. "Could not find a suitable classloader to modify from " classloaders))))))
+ (throw (IllegalStateException. (str "Could not find a suitable classloader to modify from "
+ classloaders)))))))
(defn add-dependencies
"Resolves a set of dependencies, optionally against a set of additional Maven repositories,
@@ -116,7 +89,7 @@ unless you are extending a type to this protocol."
([classloaders]
[]
(->> (reverse classloaders)
- (mapcat #(when (instance? URLClassLoader %) (.getURLs %)))
+ (mapcat #(when (dp/readable-classpath? %) (dp/classpath-urls %)))
(map str)))
([] (get-classpath (classloader-hierarchy))))

0 comments on commit f70d38b

Please sign in to comment.