Search code examples
clojureleiningenclojars

Distributing a simple library via clojars


I have implemented a hyphenation algorithm (at namespace hyphenator-clj.core), defined it as org.clojars.nikonyrh.hyphenator-clj 0.1.0 at defproject and pushed it to Clojars. Uberjar seems to have files like core__init.class, core.clj and core.class.

However when I try to use it as a dependency on an other project I get this error:

$ lein uberjar
Retrieving org/clojars/nikonyrh/hyphenator-clj/org.clojars.nikonyrh.hyphenator-clj/0.1.0/org.clojars.nikonyrh.hyphenator-clj-0.1.0.pom from clojars
Retrieving org/clojars/nikonyrh/hyphenator-clj/org.clojars.nikonyrh.hyphenator-clj/0.1.0/org.clojars.nikonyrh.hyphenator-clj-0.1.0.jar from clojars
Compiling example.core
java.io.FileNotFoundException: Could not locate org/clojars/nikonyrh/hyphenator_clj__init.class or org/clojars/nikonyrh/hyphenator_clj.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name., compiling:(core.clj:1:1)
Exception in thread "main" java.io.FileNotFoundException: Could not locate org/clojars/nikonyrh/hyphenator_clj__init.class or org/clojars/nikonyrh/hyphenator_clj.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name., compiling:(core.clj:1:1)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3657)
    at clojure.lang.Compiler.compile1(Compiler.java:7474)
    at clojure.lang.Compiler.compile1(Compiler.java:7464)
    at clojure.lang.Compiler.compile(Compiler.java:7541)
    at clojure.lang.RT.compile(RT.java:406)
    at clojure.lang.RT.load(RT.java:451)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    ...

Must I change my project's folder structure so that it matches the expected org/clojars/nikonyrh/hyphenator_clj__init.class, or can I somehow override the current behavior? If there is a good tutorial about this out there I would be happy to read it.

Basically I would like to get this example project to work. project.clj:

(defproject example "0.0.1-SNAPSHOT"
  :description ""
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojars.nikonyrh.hyphenator-clj "0.1.0"]]
  :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]
  :aot [example.core]
  :main example.core)

src/example/core.clj:

(ns example.core
  (:require [org.clojars.nikonyrh.hyphenator-clj :as h])
  (:gen-class))

(defn -main [& argv] (doseq [arg argv] (println (h/hyphenate arg :hyphen \-))))

I'm suspecting I also have the english.txt in a wrong directory, as it isn't contained in the uberjar but resource files are an other topic.


Solution

  • Ahaa at least I understand the process a bit better now, basically my require has to match the structure of the used JAR file, which may be very different from the project's name. For example cc.qbits/spandex is actually required as qbits.spandex.

    The english.txt dependency was fixed by moving it to resources folder, deploying the new version to Clojars and importing the dependency as it exists in the JAR:

    (ns example.core
      (:require [hyphenator-clj.core :as h])
      (:gen-class))
    
    (defn -main [& argv] (doseq [arg argv] (println (h/hyphenate arg :hyphen \-))))