CLASSPATH-8: fallback to java.class.path on Java 9
Starting with Java 9, the default class loader is no longer an
instance of URLClassLoader, so `classpath` returned an empty sequence.
The strategy of using URLClassLoader started with release [0.2.0] to
accommodate Java application containers (see [CLASSPATH-1] and
[CLASSPATH-2]). After this change, application containers based on
URLClassLoader should still work as expected.
On Java 9 without an application container, it appears that the
`java.class.path` system property is the only way to get the
classpath. While this is essentially a bugfix for Java 9
compatibility, it is a change in behavior, hence the version change
from 0.2 to 0.3.
Stuart Sierra
6 years ago
68 | 68 | (map io/as-file (get-urls loader))) |
69 | 69 | |
70 | 70 | (defn classpath |
71 | "Returns a sequence of File objects of the elements on the classpath." | |
71 | "Returns a sequence of File objects of the elements on the | |
72 | classpath. Defaults to searching for instances of | |
73 | java.net.URLClassLoader in the classloader hierarchy above | |
74 | clojure.lang.RT/baseLoader or the given classloader. If no | |
75 | URLClassloader can be found, as on Java 9, falls back to the | |
76 | 'java.class'path' system property." | |
72 | 77 | ([classloader] |
73 | 78 | (distinct |
74 | 79 | (mapcat |
76 | 81 | (take-while |
77 | 82 | identity |
78 | 83 | (iterate #(.getParent ^ClassLoader %) classloader))))) |
79 | ([] (classpath (clojure.lang.RT/baseLoader)))) | |
84 | ([] | |
85 | (or (seq (classpath (clojure.lang.RT/baseLoader))) | |
86 | (system-classpath)))) | |
80 | 87 | |
81 | 88 | (defn classpath-directories |
82 | 89 | "Returns a sequence of File objects for the directories on classpath." |