Skip to content

Commit f79efe1

Browse files
scgilardistuarthalloway
authored andcommitted
restore detection of cyclic load dependencies
Signed-off-by: Stuart Halloway <[email protected]>
1 parent 76c1a58 commit f79efe1

File tree

10 files changed

+124
-8
lines changed

10 files changed

+124
-8
lines changed

src/clj/clojure/core.clj

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5071,8 +5071,8 @@
50715071

50725072
(defonce ^:dynamic
50735073
^{:private true
5074-
:doc "the set of paths currently being loaded by this thread"}
5075-
*pending-paths* #{})
5074+
:doc "A stack of paths currently being loaded by this thread"}
5075+
*pending-paths* ())
50765076

50775077
(defonce ^:dynamic
50785078
^{:private true :doc
@@ -5206,8 +5206,20 @@
52065206
(doseq [arg args]
52075207
(apply load-lib prefix (prependss arg opts))))))))
52085208

5209-
;; Public
5209+
(defn- check-cyclic-dependency
5210+
"Detects and rejects non-trivial cyclic load dependencies. The
5211+
exception message shows the dependency chain with the cycle
5212+
highlighted. Ignores the trivial case of a file attempting to load
5213+
itself because that can occur when a gen-class'd class loads its
5214+
implementation."
5215+
[path]
5216+
(when (some #{path} (rest *pending-paths*))
5217+
(let [pending (map #(if (= % path) (str "[ " % " ]") %)
5218+
(cons path *pending-paths*))
5219+
chain (apply str (interpose "->" pending))]
5220+
(throw (Exception. (str "Cyclic load dependency: " chain))))))
52105221

5222+
;; Public
52115223

52125224
(defn require
52135225
"Loads libs, skipping any that are already loaded. Each argument is
@@ -5300,12 +5312,10 @@
53005312
(when *loading-verbosely*
53015313
(printf "(clojure.core/load \"%s\")\n" path)
53025314
(flush))
5303-
; (throw-if (*pending-paths* path)
5304-
; "cannot load '%s' again while it is loading"
5305-
; path)
5306-
(when-not (*pending-paths* path)
5315+
(check-cyclic-dependency path)
5316+
(when-not (= path (first *pending-paths*))
53075317
(binding [*pending-paths* (conj *pending-paths* path)]
5308-
(clojure.lang.RT/load (.substring path 1)))))))
5318+
(clojure.lang.RT/load (.substring path 1)))))))
53095319

53105320
(defn compile
53115321
"Compiles the namespace named by the symbol lib into a set of

src/script/run_tests.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ clojure.test-clojure.java.javadoc
2323
clojure.test-clojure.java.shell
2424
clojure.test-clojure.java-interop
2525
clojure.test-clojure.keywords
26+
clojure.test-clojure.load
2627
clojure.test-clojure.logic
2728
clojure.test-clojure.macros
2829
clojure.test-clojure.main

test/clojure/test_clojure/load.clj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
9+
(ns clojure.test-clojure.load
10+
(:use clojure.test))
11+
12+
(deftest test-load
13+
(testing "Should ignore self-loads without comment"
14+
(is (nil? (require 'clojure.test-clojure.load.cyclic0))))
15+
(testing "Should reject cyclic dependencies"
16+
(testing "a->b->a"
17+
(is (thrown-with-msg? Exception #".*Cyclic load dependency.*"
18+
(require 'clojure.test-clojure.load.cyclic1))))
19+
(testing "a->b->c->d->b"
20+
(is (thrown-with-msg? Exception #".*Cyclic load dependency.*"
21+
(require 'clojure.test-clojure.load.cyclic3))))))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
;
9+
; Author: Stephen C. Gilardi
10+
11+
(ns clojure.test-clojure.load.cyclic0
12+
(:require clojure.test-clojure.load.cyclic0))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
;
9+
; Author: Stephen C. Gilardi
10+
11+
(ns clojure.test-clojure.load.cyclic1
12+
(:require clojure.test-clojure.load.cyclic2))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
;
9+
; Author: Stephen C. Gilardi
10+
11+
(ns clojure.test-clojure.load.cyclic2
12+
(:require clojure.test-clojure.load.cyclic1))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
;
9+
; Author: Stephen C. Gilardi
10+
11+
(ns clojure.test-clojure.load.cyclic3
12+
(:require clojure.test-clojure.load.cyclic4))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
;
9+
; Author: Stephen C. Gilardi
10+
11+
(ns clojure.test-clojure.load.cyclic4
12+
(:require clojure.test-clojure.load.cyclic5))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
;
9+
; Author: Stephen C. Gilardi
10+
11+
(ns clojure.test-clojure.load.cyclic5
12+
(:require clojure.test-clojure.load.cyclic6))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
;
9+
; Author: Stephen C. Gilardi
10+
11+
(ns clojure.test-clojure.load.cyclic6
12+
(:require clojure.test-clojure.load.cyclic4))

0 commit comments

Comments
 (0)