Whenever I start a project, an error occurs :main namespace specified in project.clj

Viewed 71

Whichever github project I run I get the same error.

Now I have started a simple example from the book clojure for brave and true and the same program appears.

(ns clojure-noob.core
  (:gen-class))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "I'm a little teapot!"))

error is

>   PS C:\Users\danny\New folder\cftbat-code> lein run
No :main namespace specified in project.clj.

what can i do and what i am doing wrong?

1 Answers

This is surprising! Apparently typing lein new myproj does not include a necessary line in the result. In particular, your project.clj file needs a line like this:

  :main myproj.core

Change it to look like the following:

(defproject myproj "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :dependencies [[org.clojure/clojure "1.10.3"]]
  :repl-options {:init-ns myproj.core}
  :main myproj.core
  )

and

(ns myproj.core)

(defn -main
  "I don't do a whole lot."
  [& args]
  (println "Hello, World!" args))

with result

> lein clean; lein run abc
Hello, World! (abc)

Another option

Having said that, I never use lein new xxx anymore. Instead, I just clone this template project, then modify it.

Just check out the README and follow along!


Extra details

You can also specify the "main function" to run on the command line. Since the name of the default "main function" is -main, you can tell lein run the namespace containing the -main function by typing:

> lein clean ; lein run :main myproj.core
Hello, World! nil

If your "main function" is not -main, then type something like

> lein clean ; lein run :main myproj.core/foo

When you have compilation failues (especially if macros are involved), it is always safest to delete all previous *.class files via lein clean. If you don't, maybe one in a hundred times you will get very strange failures that cannot be explained.

I find it safest to define and always use an alias:

alias lcr="lein do clean, run"
alias lct="lein do clean, test"

The version with do is about 1 second faster than lein clean; lein run, but don't forget the comma!


How to avoid

OK, I just remembered a way to avoid the problem. Just type:

lein new app myapp

This will include the line

  :main ^:skip-aot myapp.core

which was missing when you just type lein new myproj (i.e. with out the app part).

Related