Mastering lein run

In hangman with lein run, Incanter, and opencsv – Counterclockwise is here, too I mentioned the hangman project in which I’d come across

lein run

.

I decided to use it in a side project of mine – librarian-clojure. I ran

lein run

to see what would happen.

jacek:~/oss/librarian-clojure
$ lein run
No :main namespace specified in project.clj.

Ouch, but not much. The error message said it all. Easy stuff, wasn’t it?

It also reminded me about Procfile for Heroku where I entered a quite similar command.

jacek:~/oss/librarian-clojure
$ cat Procfile
web: lein run -m librarian-clojure.core $PORT

It worked fine on the command line.

jacek:~/oss/librarian-clojure
$ lein run -m librarian-clojure.core 8080
...
2012-02-11 20:29:46.756:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
2012-02-11 20:29:46.773:INFO::jetty-6.1.25
2012-02-11 20:29:46.857:INFO::Started SocketConnector@0.0.0.0:8080

With

:main librarian-clojure.core

in project.clj I ran

lein run

again.

jacek:~/oss/librarian-clojure
$ lein run
Exception in thread "main" clojure.lang.ArityException: Wrong number of args (0) passed to: core$-main
     at clojure.lang.AFn.throwArity(AFn.java:437)
     at clojure.lang.AFn.invoke(AFn.java:35)
     at clojure.lang.Var.invoke(Var.java:397)
     at user$eval53.invoke(NO_SOURCE_FILE:1)
     at clojure.lang.Compiler.eval(Compiler.java:6465)
     at clojure.lang.Compiler.eval(Compiler.java:6455)
     at clojure.lang.Compiler.eval(Compiler.java:6431)
     at clojure.core$eval.invoke(core.clj:2795)
     at clojure.main$eval_opt.invoke(main.clj:296)
     at clojure.main$initialize.invoke(main.clj:315)
     at clojure.main$null_opt.invoke(main.clj:348)
     at clojure.main$main.doInvoke(main.clj:426)
     at clojure.lang.RestFn.invoke(RestFn.java:421)
     at clojure.lang.Var.invoke(Var.java:405)
     at clojure.lang.AFn.applyToHelper(AFn.java:163)
     at clojure.lang.Var.applyTo(Var.java:518)
     at clojure.main.main(main.java:37)

Clojure is known for “its elaborative exception messages” (quoting Stuart Halloway who said that the situation is “because Rick doesn’t make mistakes” at 00:47:30), but in this particular case, it didn’t take much to figure out that the -main function in librarian-clojure/core.clj offers no no-args version of itself.

With a small change that ultimately helped me to master the format of a function definition with different args, the project boots up now with a simple

lein run

.

(defn -main
  ([] (-main 9999))
  ([port] (run-jetty app {:port (Integer. port)})))

I believe I need a

librarian-clojure/main.clj

to copy the above method to and have another one to fire up a browser with the URL for the application – something similar to ClojureScript One’s repl.clj.

People interested in

lein run

‘s internals are requested to visit leiningen.run.

Be Sociable, Share!
This entry was posted in Languages.
%d bloggers like this: