clojurecounterclockwise

ClassNotFoundException on use of another ns


As simple as this question is, I can't seem to find the right way for different namespaces in the same directory to validly refer to one another. I have two files:

project_root/src/babbler/core.clj:

(ns babbler.core
  (:gen-class)
  (use '[clojure.string :only (join split)]))

(defn foo [] "Foo")

and then project_root/src/babbler/bar.clj:

(ns babbler.bar)

(use [babbler.core :as babble])

This file also contains a main method, which is specified in my project.clj via :main babbler.bar

My entire structure is that generated by counterclockwise, with with default leiningen template.

The result of running lein repl is this:

Exception in thread "main" java.lang.ClassNotFoundException: babbler.core, compiling:(babbler/bar.clj:3:1)
    at clojure.lang.Compiler.analyze(Compiler.java:6380)
    at clojure.lang.Compiler.analyze(Compiler.java:6322)
    at clojure.lang.Compiler$VectorExpr.parse(Compiler.java:3024)
    at clojure.lang.Compiler.analyze(Compiler.java:6363)
    at clojure.lang.Compiler.analyze(Compiler.java:6322)

(...)


Solution

  • Your use should be inside the definition of the namespace:

    (ns babbler.bar
      (use [babbler.core :as babble]))
    

    In fact use is discouraged, you may want to write it as:

    (ns babbler.bar
      (:require [babbler.core :as babble :refer [foo]]))
    

    That way you can call any function f from the babbler.core namespace as babble/f, and you can call foo directly. In addition, your file has information about where foo comes from so you or someone else won't need to go searching for it.