views:

177

answers:

2

I have a hello.clj as follows.

(ns hello) 
(defn hi [] (println "HI"))

Normally, I can use this function from main.clj as follows. The hello.clj is in the same directory that contains main.clj. And the classpath includes . (current path).

(use 'hello)
(hi)

How can I use this hello.clj for the 'lein uberjar'?

I used 'lein new myproject; lein deps' to get the following structure.

.
|-- README
|-- classes
|   `-- myproject
|-- lib
|   |-- clojure-1.2.0-beta1.jar
|   |-- clojure-contrib-1.2.0-beta1.jar
|   `-- lucene-core-3.0.2.jar
|-- project.clj
|-- src
|   `-- myproject
|       `-- core.clj
`-- test
    `-- myproject
        `-- test
            `-- core.clj

project.clj is as follows.

(defproject myproject "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.2.0-beta1"]
                 [org.clojure/clojure-contrib "1.2.0-beta1"]
                 [org.apache.lucene/lucene-core "3.0.2"]]
  :main myproject.core)    

And core.clj is as follows.

(ns myproject.core
  (:gen-class))

(use 'hello) 

(defn test1 [] (println "hello"))

(defn -main [& args]
  (do 
    (println "Welcome to my project! These are your args:" args)
    (test1)
    (hi)))

Now, where do I put the hello.clj? I tried to copy it to myproject/src directory and run uberjar to get the jar. But, running the jar causes this error message.

prosseek:myproject smcho$ java -jar myproject-1.0.0-SNAPSHOT-standalone.jar a d d
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.io.FileNotFoundException: Could not locate hello__init.class or hello.clj on classpath:  (core.clj:0)
...
  • What might be wrong? Error messages says hello.clj is not on the class path. But, how to setup the classpath with 'lein uberjar'?

I uploaded the project here.

A: 

Hi,

hello.clj should be inside your project-root/src. With that it should work. For an example of a similar project, see leiningen project. The lancet namespace is inside src:

http://github.com/technomancy/leiningen/tree/master/src/

Ramakrishnan Muthukrishnan
I misunderstood your question a bit.:) Yes, if you are interested to make hello as part of your project, yes, you put it inside <root>/src/myproject and declar ethe namespace as myproject.hello. But if you are using another namespace from another project (like lancet used in leiningen), then the above approach of putting hello.clj in its own namespace and adding under <root>/src works fine too.
Ramakrishnan Muthukrishnan
+6  A: 

You put hello.clj under src/myproject so it's ns should be myproject.hello. With this file structure, I would expect hello.clj to say (ns myproject.hello) and for core.clj to say (use 'myproject.hello).

When I make those changes, I get:

$ java -jar myproject-standalone.jar a b c
Welcome to my project! These are your args: (a b c)
hello
HI
Alex Miller
Yes, it works! Thanks a lot.
prosseek
What you were trying to do with (ns hello) is called a single-segment namespace. While it works OK when you are just in Clojure-land, once you perform AOT in order to be launchable as an uberjar myproject.core becomes Java bytecode and can't get at the hello namespace since it doesn't have a java package.
technomancy