Opening leiningen project in emacs/cider raises classpath error

154 Views Asked by At

I'm learning Clojure with 'Clojure for the Brave and True' book and use emacs, cider and leiningen. I've created a project.

lein new app the-divine-cheese-code

Then I've added to source files to the project.

the-divine-cheese-code\src\the_divine_cheese_code\core.clj the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj

In 'core.clj' I refer to the 'svg.clj' namespace.

the-divine-cheese-code\src\the_divine_cheese_code\core.clj

(ns the-divine-cheese-code.core)
;; Ensure that the SVG code is evaluated
(require 'the-divine-cheese-code.visualization.svg)
;; Refer the namespace so that you don't have to use the 
;; fully qualified name to reference svg functions
(refer 'the-divine-cheese-code.visualization.svg)

(def heists [{:location "Cologne, Germany"
              :cheese-name "Archbishop Hildebold's Cheese Pretzel"
              :lat 50.95
              :lng 6.97}
             {:location "Zurich, Switzerland"
              :cheese-name "The Standard Emmental"
              :lat 47.37
              :lng 8.55}
             {:location "Marseille, France"
              :cheese-name "Le Fromage de Cosquer"
              :lat 43.30
              :lng 5.37}
             {:location "Zurich, Switzerland"
              :cheese-name "The Lesser Emmental"
              :lat 47.37
              :lng 8.55}
             {:location "Vatican City"
              :cheese-name "The Cheese of Turin"
              :lat 41.90
              :lng 12.45}])

(defn -main
  [& args]
  (println (points heists)))

the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj

(ns the-divine-cheese-code.visualization.svg)

(defn latlng->point
  "Convert lat/lng map to comma-separated string" 
  [latlng]
  (str (:lat latlng) "," (:lng latlng)))

(defn points
  [locations]
  (clojure.string/join " " (map latlng->point locations)))

Here is the project's entire dir structure.

the-divine-cheese-code              
the-divine-cheese-code\.gitignore               
the-divine-cheese-code\.hgignore                
the-divine-cheese-code\.nrepl-port              
the-divine-cheese-code\CHANGELOG.md             
the-divine-cheese-code\doc              
the-divine-cheese-code\doc\intro.md             
the-divine-cheese-code\LICENSE              
the-divine-cheese-code\project.clj              
the-divine-cheese-code\README.md                
the-divine-cheese-code\resources                
the-divine-cheese-code\src              
the-divine-cheese-code\src\the_divine_cheese_code               
the-divine-cheese-code\src\the_divine_cheese_code\core.clj              
the-divine-cheese-code\src\the_divine_cheese_code\visualization             
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj             
the-divine-cheese-code\target               
the-divine-cheese-code\target\default               
the-divine-cheese-code\target\default\classes               
the-divine-cheese-code\target\default\classes\META-INF              
the-divine-cheese-code\target\default\classes\META-INF\maven                
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code             
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code              
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code\pom.properties
the-divine-cheese-code\target\default\repl-port             

the-divine-cheese-code\target\default\stale
the-divine-cheese-code\target\default\stale\leiningen.core.classpath.extract-native-dependencies
the-divine-cheese-code\test
the-divine-cheese-code\test\the_divine_cheese_code
the-divine-cheese-code\test\the_divine_cheese_code\core_test.clj

When I run the project with 'lein run' it executes successfully. However, when I open the core.clj file with emacs/cider and try to compile it, I get classpath error.

CompilerException java.io.FileNotFoundException: Could not locate 
the_divine_cheese_code/visualization/svg__init.class or 
the_divine_cheese_code/visualization/svg.clj on classpath. Please check 
that namespaces with dashes use underscores in the Clojure file name., 
compiling:(c:/temp/the-divine-cheese-code/src/the_divine_cheese_code/core.clj:2:1)

CIDER compiles sources sucessfully if I put them in the same directory (changing namespace correspondingly).

(ns the-divine-cheese-code.core)
(require 'the-divine-cheese-code.svg)
(refer 'the-divine-cheese-code.svg)

(def heists [{:location "Cologne, Germany"
    ...

So maybe the issue is dealt with OS. I use Windows 7, which is not primary OS for Emacs/CIDER.

After some experimenting I found that the CIDER works without :refer

(ns the-divine-cheese-code.core
  (:require [the-divine-cheese-code.visualization.svg]))

This looks like a CIDER bug and 'lein run' predictably gives error in this case. If I make it the right way

(ns the-divine-cheese-code.core
  (:require [the-divine-cheese-code.visualization.svg :refer :all]))

the CIDER now gives another error:

Caused by java.lang.IllegalStateException
latlng->point already refers to:
#'the-divine-cheese-code.svg/latlng->point in namespace:
the-divine-cheese-code.core
2

There are 2 best solutions below

5
On

Would suggest to use the options provided by the ns macro instead of naked require and refer statements - this is the recommended way of doing imports/requires in Clojure and most of the tooling is written with this way of managing namespaces in mind. Even if the below code still doesn't work in CIDER, it will be easier to diagnose it:

;; the-divine-cheese-code\src\the_divine_cheese_code\core.clj

(ns the-divine-cheese-code.core
  (:require [the-divine-cheese-code.visualization.svg :refer :all]))

(def heists ...)

(defn- main ...)
0
On

In my case, the error went away after I renamed (to the same name) src/the_divine_cheese_code/ folder and it's contents recursively.

Not sure what caused the issue. My guess is that character encoding was screwed up. I created both the file and folder in Emacs and done the renaming in Double Commander.