lein pom - :classifier clause does not get generated in pom.xml - clojure

I'm using the Stanford CoreNLP library, and for this I need to use a classifier clause. In a pom.xml, it should look like this :
<dependencies>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.5.0</version>
<classifier>models</classifier>
</dependency>
</dependencies>
To achieve this, my project.clj looks like this :
(defproject sviepbd "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.6.0"]
;; [...] other dependencies
;; Stanford CoreNLP
[edu.stanford.nlp/stanford-corenlp "3.5.0"] ;; A Suite of Core Natural Language Processing Tools
[edu.stanford.nlp/stanford-corenlp "3.5.0" :classifier "models"]
]
:main ^:skip-aot sviepbd.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
After running lein deps, the dependencies get fetched properly, and I can use them when working in the REPL. However, after running lein pom it is my constatation that the classifierclause does not appear in the generated pom.xml.
What have I done wrong?
I'm using Leiningen 2.3.4; the reason I need a proper pom.xml is that I'm using Counterclockwise as an editor.

It works on Leiningen 2.5.0; anyone with that issue should upgrade.

Related

Adding dependencies to clojure projects using lein

Despite adding the desired dependency to my project.clj file,
(defproject word-tree "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.10.1"]
[org.clojure/clojurescript "1.10.520"]
[clojure-opennlp "0.5.0"] ; <----------------------here
[reagent "0.8.1"]]
...
I am unable to access the functions that the dependency provides.
After referencing the namespace in one of my files,
(ns word-tree.suffix-tree
(:require [clojure.string :as str]
[opennlp.nlp :as nlp])) ; <-----this is the namespace of the dependency
I get this error:
No such namespace: opennlp.nlp, could not locate opennlp/nlp.cljs, opennlp/nlp.cljc, or JavaScript source providing "opennlp.nlp"
The weirdest part is that when I run lein deps :tree the dependency shows up!
$ lein deps :tree
...
[cider/piggieback "0.4.1" :scope "test"]
[cljfmt "0.5.7"]
[rewrite-clj "0.5.2"]
[rewrite-cljs "0.4.3"]
[clojure-complete "0.2.5" :exclusions [[org.clojure/clojure]]]
[clojure-opennlp "0.5.0"] <------------------------------------------------here!!!
[instaparse "1.4.9"]
[org.apache.opennlp/opennlp-tools "1.9.0"]
[figwheel-sidecar "0.5.19" :scope "test"]
...
For my project I really want to use this dependency but it's not working. Any advice would be most welcome. Thanks.
It seems to me the problem is that the library is for Clojure on the JVM only, and you are trying to use it on a ClojureScript project.
No such namespace: opennlp.nlp, could not locate opennlp/nlp.cljs, opennlp/nlp.cljc, or JavaScript source providing "opennlp.nlp"
The compiler tried to look for ClojureScript code (extension .cljs) or compatible with both Clojure and ClojureScript (extension .cljc) or plain JavaScript, but found none.

How to get `lein-repl` to use `user` instead of `main` for development purposes

I'm trying to set up a development version and a production version of my application using leiningen via the project.clj.
How can I have both? Because I have to comment out the :main part of my project.clj in order to get access to the development version when I use lein repl.
So I am using stuartsierra/reloaded leiningen template which has a nice development environment.
It comes with no :main key and when I added one that's when I stopped getting the development version of my project.
Instead of seeing
user=>
When I type lein repl I end up seeing my main, which is in the jaribu namespace
io.wakamau.jaribu=> ;; my main
The solution that seems to work is to comment out the :main part of the project.clj.
(defproject io.wakamau/jaribu "0.1.0-SNAPSHOT"
:description "trying out pedestal and component"
:url "https://github.com/kevinmungai/jaribu"
:license {:name "TODO: Choose a license"
:url "http://choosealicense.com/"}
:dependencies [[org.clojure/clojure "1.10.0"]
[com.stuartsierra/component "0.3.2"]]
:profiles {:dev
{:dependencies [[org.clojure/tools.namespace 0.2.11"]
[com.stuartsierra/component.repl "0.2.0"]]
:source-paths ["dev"]}
:uberjar {:aot [io.wakamau.jaribu]}}
:main ^{:skip-aot true} io.wakamau.jaribu
:min-lein-version "2.0.0")
trying out
lein repl
results in:
io.wakamau.jaribu=>
when the :main is commented out:
(defproject io.wakamau/jaribu "0.1.0-SNAPSHOT"
...
;; :main ^{:skip-aot true} io.wakamau.jaribu
:min-lein-version "2.0.0")
the result is:
user=>
I have to admit that I don't know much about using leiningen.
You can specify :repl-options {:init-ns io.wakamau.jaribu=>} in project.clj. You can also specify constants for different environments in profiles.clj, e.g., :dev {:main io.wakamau.jaribu}. Also see How do I start the REPL in a user defined namespace?.

Can't run uberjar with Leiningen 2.5.2

I was trying to pick up Clojure again, but am stumbling right at the beginning. I downloaded lein, and copied the following project.clj and a hello.clj to be absolutely sure that I have a minimal working example.
project.clj:
(defproject hello "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.7.0"]]
:uberjar {:aot :all}
:main hello.core
)
hello.clj:
(ns hello.core
(:gen-class)
)
(defn -main
"This should be pretty simple."
[]
(println "Hello, World!"))
When I run './lein uberjar' I get these warnings:
Warning: specified :main without including it in :aot.
Implicit AOT of :main will be removed in Leiningen 3.0.0.
If you only need AOT for your uberjar, consider adding :aot :all into your
:uberjar profile instead.
Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method.
Created .../target/hello-0.1.0-SNAPSHOT.jar
Created .../target/hello-0.1.0-SNAPSHOT-standalone.jar
Trying to run this either with ./lein run or with java -jar ./target/hello-0.1.0-SNAPSHOT-standalone.jar results in exceptions:
Can't find 'hello.core' as .class or .clj for lein run: please check the spelling.
Exception in thread "main" java.io.FileNotFoundException: Could not locate hello/core__init.class or hello/core.clj on classpath., compiling:(/private/var/folders/28/bk6d4xj123b0xvsvk91_1jg80009rn/T/form-init1007755193774766954.clj:1:125)
So what is my problem here?
:uberjar {:aot :all} -> :profiles {:uberjar {:aot :all}}
And move hello.clj into ./src/hello directory and rename it to core.clj

"'cljsbuild' not a task"

using lein for clojure, attempting to use the clojurescript plugin.
followed all readme.md install steps, project.clj has
:dependencies [[org.clojure/clojure "1.7.0"]
[org.clojure/clojurescript "0.0-3126"]]
;; lein-cljsbuild plugin to build a CLJS project
:plugins [[lein-cljsbuild "1.0.6"]]
:hooks [leiningen.cljsbuild]
I cannot seem to get lein to recognize the plugin and am not sure what is being the gremlin.
C:\Functional_Languages\Clojure\clojurescript_master\!work\modern-cljs>lein cljsbuild once
'cljsbuild' is not a task. See 'lein help'.
C:\Functional_Languages\Clojure\clojurescript_master\!work\modern-cljs>lein compile
C:\Functional_Languages\Clojure\clojurescript_master\!work\modern-cljs>lein cljsbuild once
'cljsbuild' is not a task. See 'lein help'.
C:\Functional_Languages\Clojure\clojurescript_master\!work\modern-cljs>lein -v
Leiningen 2.5.1 on Java 1.8.0_51 Java HotSpot(TM) 64-Bit Server VM
C:\Functional_Languages\Clojure\clojurescript_master\!work\modern-cljs>
If you use lein new mies ... for getting the project file, and execute the command, the automatically generated project.clj file should be modified.
This is an example that shows the change:
Before:
(defproject simple "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://example.com/FIXME"
:dependencies [[org.clojure/clojure "1.7.0"]
[org.clojure/clojurescript "1.7.122" :classifier "aot"
:exclusion [org.clojure/data.json]]
[org.clojure/data.json "0.2.6" :classifier "aot"]]
:jvm-opts ^:replace ["-Xmx1g" "-server"]
:plugins [[lein-npm "0.6.1"]]
:npm {:dependencies [[source-map-support "0.3.2"]]}
:source-paths ["src" "target/classes"]
:clean-targets ["out" "release"]
:target-path "target")
After
(defproject simple "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://example.com/FIXME"
:dependencies [[org.clojure/clojure "1.7.0"]
[org.clojure/clojurescript "1.7.122" :classifier "aot"
:exclusion [org.clojure/data.json]]
[org.clojure/data.json "0.2.6" :classifier "aot"]]
:node-dependencies [[source-map-support "0.2.8"]]
:jvm-opts ^:replace ["-Xmx1g" "-server"]
:plugins [[lein-npm "0.6.1"]
[lein-cljsbuild "1.0.4"]]
:npm {:dependencies [[source-map-support "0.3.2"]]}
:source-paths ["src" "target/classes"]
:clean-targets ["out" "release"]
:target-path "target"
:cljsbuild {
:builds [{:id "simple"
:source-paths ["src"]
:compiler {
:main simple.core
:output-to "out/simple.js"
:output-dir "out"
:optimizations :none
:target :nodejs
:cache-analysis true
:source-map true}}]})
As you see, you need to add lein-cljsbuild plugins with build information. For further explanation, refer to http://www.mase.io/code/clojure/node/2015/01/24/getting-started-with-clojurecript-and-node/
If you don't want the change, just run ./scripts/build.
I think the problem is that your project.clj file is lacking a :cljsbuild stanza/key which defines the various parameters required to compile the clojurescript source files.
Have a look at Modern Clojurescript Tutorial for more details or you can check out my clojurescript file upload example to get an idea of how you can define :cljsbuild targets.

Using a Clojure/ClojureScript crossover library

I'm working on a library that works with both Clojure and ClojureScript.
Here's the project.clj for the library:
(defproject libtest "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]]
:plugins [[lein-cljsbuild "0.3.0"]]
:cljsbuild
{:crossovers [libtest],
:crossover-jar true
:jar true
:builds
[{:source-paths ["src/libtest"], :crossover-path "src/libtest"}]})
I'm including it as a dependency in another project. To get it to work from the ClojureScript side of my project, I had to add the exact namespace as a crossover under the cljsbuild key of my project.clj:
(defproject some-other-project
...
:dependencies [[org.clojure/clojure "1.5.0"]
[libtest "0.1.0-SNAPSHOT"]]
:cljsbuild {
:builds [{
...
:crossovers [libtest.core]
...
My question is, is this necessary? If it's on the classpath, why must I specifically tell it what namespaces I'm going to use? This can't scale well if I need to use dozens of namespaces, some of which will reference other namespaces and etc.
This is not a perfect solution, but works for me. When a namespace is specified as a crossover, its children are added recursively. So :crossovers [libtest] will add libtest.core too. If you specify a :crossover-path, you can see what files are generated into that directory.