Permalink
Browse files

restore detection of cyclic load dependencies

Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
  • Loading branch information...
scgilardi authored and stuarthalloway committed Sep 30, 2010
1 parent eb85cf9 commit f86db9cc68773dd3e4a166c1ff7b81e4a98aa602
View
@@ -4668,8 +4668,8 @@
(defonce
^{:private true
- :doc "the set of paths currently being loaded by this thread"}
- *pending-paths* #{})
+ :doc "A stack of paths currently being loaded by this thread"}
+ *pending-paths* ())
(defonce
^{:private true :doc
@@ -4803,8 +4803,20 @@
(doseq [arg args]
(apply load-lib prefix (prependss arg opts))))))))
-;; Public
+(defn- check-cyclic-dependency
+ "Detects and rejects non-trivial cyclic load dependencies. The
+ exception message shows the dependency chain with the cycle
+ highlighted. Ignores the trivial case of a file attempting to load
+ itself because that can occur when a gen-class'd class loads its
+ implementation."
+ [path]
+ (when (some #{path} (rest *pending-paths*))
+ (let [pending (map #(if (= % path) (str "[ " % " ]") %)
+ (cons path *pending-paths*))
+ chain (apply str (interpose "->" pending))]
+ (throw (Exception. (str "Cyclic load dependency: " chain))))))
+;; Public
(defn require
"Loads libs, skipping any that are already loaded. Each argument is
@@ -4897,12 +4909,10 @@
(when *loading-verbosely*
(printf "(clojure.core/load \"%s\")\n" path)
(flush))
-; (throw-if (*pending-paths* path)
-; "cannot load '%s' again while it is loading"
-; path)
- (when-not (*pending-paths* path)
+ (check-cyclic-dependency path)
+ (when-not (= path (first *pending-paths*))
(binding [*pending-paths* (conj *pending-paths* path)]
- (clojure.lang.RT/load (.substring path 1)))))))
+ (clojure.lang.RT/load (.substring path 1)))))))
(defn compile
"Compiles the namespace named by the symbol lib into a set of
@@ -0,0 +1,21 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns clojure.test-clojure.load
+ (:use clojure.test))
+
+(deftest test-load
+ (testing "Should ignore self-loads without comment"
+ (is (nil? (require 'clojure.test-clojure.load.cyclic0))))
+ (testing "Should reject cyclic dependencies"
+ (testing "a->b->a"
+ (is (thrown-with-msg? Exception #".*Cyclic load dependency.*"
+ (require 'clojure.test-clojure.load.cyclic1))))
+ (testing "a->b->c->d->b"
+ (is (thrown-with-msg? Exception #".*Cyclic load dependency.*"
+ (require 'clojure.test-clojure.load.cyclic3))))))
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic0
+ (:require clojure.test-clojure.load.cyclic0))
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic1
+ (:require clojure.test-clojure.load.cyclic2))
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic2
+ (:require clojure.test-clojure.load.cyclic1))
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic3
+ (:require clojure.test-clojure.load.cyclic4))
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic4
+ (:require clojure.test-clojure.load.cyclic5))
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic5
+ (:require clojure.test-clojure.load.cyclic6))
@@ -0,0 +1,12 @@
+; Copyright (c) Rich Hickey. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+;
+; Author: Stephen C. Gilardi
+
+(ns clojure.test-clojure.load.cyclic6
+ (:require clojure.test-clojure.load.cyclic4))

0 comments on commit f86db9c

Please sign in to comment.