Leiningen Bug In Producing Uberjars Or Misunderstanding? - clojure

What can cause lein uberjar to fail with "Caused by: java.lang.ClassNotFoundException" errors when lein run runs my app successfully? I'm using leiningen 2.5.1.
It looks like leiningen provides profiles as a way to make custom environments for certain tasks. However, I don't believe a profile difference between what is happening with lein run and lein uberjar is responsible because ...
1) I tried producing the uberjar with every possible profile, via lein with-profile <profile> for every <profile> named in the output of lein show-profiles.
2) I ran lein with-profile uberjar run, and no errors arose.
In case the answer to this problem and similar problems might be specific to the classes and dependencies involved, it is classes related to Overtone that produce the ClassNoteFoundException errors.
My project.clj file looks like:
(defproject cochlea "0.1.0-SNAPSHOT"
:description "An interactive ear training GUI application"
:url "http://github.com/seewalker/cochlea"
:license {:name "GPL v3"
:url "http://www.gnu.org/copyleft/gpl.html"}
:repositories {"conjars" "http://conjars.org/repo"}
:dependencies [[org.clojure/clojure "1.5.1"]
[overtone "0.9.1"]
[org.clojure/tools.trace "0.7.5"]
[org.clojure/java.jdbc "0.3.7"]
[postgresql "9.1-901.jdbc4"]
[environ "0.5.0"]
[incanter "1.9.0"]
[clj-time "0.9.0"]
[me.raynes/conch "0.8.0"]
[seesaw "1.4.2" :exclusions [org.clojure/clojure]]]
:profiles { :uberjar {:aot :all} }
:repl-options { :timeout 120000}
:main cochlea.core
:target-path "target/%s")

Related

Run more than one lein task at the same time

I am currently newbie in Leiningen project. I want to compile less to css using lein-less and minify-assets on the fly so I found that I should use lein less auto for the less file and lein minify-assets watch for javascripts and HTML file.
I am using lein-cascade to operate them but it just still on the lein less auto task and not go to lein minify-assets watch
This is my project code
(defproject indecorlein "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.8.0"]]
:plugins [[lein-asset-minifier "0.4.3"]
[lein-less "1.7.5"]
[lein-cascade "0.1.2"]]
:min-lein-version "2.5.0"
:cascade {
"lessc" [["less" "auto"]]
"min" [["minify-assets" "watch"]]
"amp" ["lessc" "min"]
}
:less {:source-paths ["dev/resources/less"]
:target-path "dev/resources/css"}
:minify-assets [
[:html {:source "dev/resources/html" :target "dev/minified/html"}]
[:css {:source "dev/resources/css" :target "dev/minified/css/styles.min.css"}]
[:js {:source ["dev/res/js"] :target "dev/minified/js/amp.min.js"}]])
Maybe there's a solution about this or me just run the tasks on separate terminal tabs.
You can use lein-pdo plugin. Add it into your plugins and define an alias:
:plugins [...
[lein-pdo "0.1.1"]]
:aliases {"watch" ["pdo" ["less" "auto"]
["minify-assets" "watch"]]}
Then you can run lein watch which will run both tasks at the same time.
The problem is that both lein less auto and lein minify-assets watch do not return. I've used lein less auto in the past in a console on its own.

lein ring server-headless fails when including datomic dependency

My goal is to create a web application using compojure and attach datomic as database. Individually, these two components work fine. However, when I try to start the server with
lein ring server-headless (including datomic as a dependency) with an enourmous error. The head of the error output:
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/jetty/util/component/AggregateLifeCycle, compiling:(ring/adapter/jetty.clj:1:1)
at clojure.lang.Compiler.load(Compiler.java:7391)
at clojure.lang.RT.loadResourceScript(RT.java:372)
at clojure.lang.RT.loadResourceScript(RT.java:363)
at clojure.lang.RT.load(RT.java:453)
at clojure.lang.RT.load(RT.java:419)
at clojure.core$load$fn__5677.invoke(core.clj:5893)
using the project.clj
(defproject pinvest "0.1.0-SNAPSHOT"
:description "foobar"
:min-lein-version "2.0.0"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/core.async "0.3.442"]
[org.clojure/tools.namespace "0.2.11"]
[compojure "1.5.1"]
[ring/ring-defaults "0.2.1"]
[com.datomic/clj-client "0.8.606"]]
:plugins [[lein-ring "0.9.7"]]
:ring {:handler pinvest.handler/app}
:profiles
{:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
[ring/ring-mock "0.3.0"]]}})
Initially generated with lein new compojure foo. The dependency com.datomic/clj-client is causing the problem in starting the server.
I tried excluding some dependencies, by making my project.clj with
[com.datomic/clj-client "0.8.606"
:exclusions [org.eclipse.jetty/jetty-http
org.eclipse.jetty/jetty-util
org.eclipse.jetty/jetty-client]]
but that just results in
clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: org.eclipse.jetty.client.HttpClient, compiling:(cognitect/http_client.clj:1:1)
Any help would be greatly appriciated.
PS. I'm a newbie to clojure, and these error messages are just impossible to understand
Try not to use jetty. Someone from the Slack group who came up with a very similar problem now uses this combination (http-kit in place of jetty):
[com.datomic/datomic-free "0.9.5544"] [ring/ring-core "1.5.0"] [http-kit "2.2.0"]
I ran into this issue too and could find no workaround. From what I understand it looks like ring-core is using an older jetty adapter for legacy purposes. I've found https://github.com/sunng87/ring-jetty9-adapter a worthy replacement as a ring dependancy so far with no further issues in my setup:
[com.datomic/clj-client "0.8.606" :exclusions [org.eclipse.jetty/jetty-http org.eclipse.jetty/jetty-util org.eclipse.jetty/jetty-client]]
[info.sunng/ring-jetty9-adapter "0.10.0"]
It's odd. The :exclusion worked for me(but I see it did not work for you). It's documented here
[com.datomic/client-pro "0.8.28"
:exclusions [org.eclipse.jetty/jetty-client
org.eclipse.jetty/jetty-http
org.eclipse.jetty/jetty-util]]

cannot run ring with lein

I am trying my first run with ring and lein, and I am facing problems in getting it to run. I have taken this example from the book "Web development with Clojure", chapter 1, and also from https://quickleft.com/blog/your-first-clojure-web-app/ . The code from both these sites give me the same error - Class Not Found.
I have the following project.clj
(defproject myfirstwebapp "0.1.1"
:description "A hello world for a Ring based web app"
:dependencies [[org.clojure/clojure "1.8.0"]
[ring "1.4.0"]]
:plugins [[lein-ring "0.9.7"]]
:dev-dependencies [[lein-ring "0.9.7"]]
:ring {:handler myfirstwebapp.core/app})
And the following core.clj
(ns myfirstwebapp.core)
(defn app [req]
{:status 200
:headers {"content-Type" "text/html"}
:body "Hello World!"})
And the commands I ran were these:
lein new myfirstwebapp
edit project.clj as above
cd myfirstwebapp
lein deps
edit src/myfirstwebapp/core.clj as above
lein ring server
And now I am getting errors like:
Exception in thread "main" java.lang.ClassNotFoundException: leiningen.core.project$reduce_repo_step, compiling:(C:\Users\ROG\form-init7789757414629005682.clj:1:17608)
Is there some mismatch between the versions of different components that I am using? Or something else?
It is a bug in lein 2.6.0. Fixed in 2.6.1

Dependencies in a clojurescript with leiningen

I am seriously pulling my hair right now! I am a total noob at clojure: I can't seem to be able to get a simple clojurescript compilation done without this error:
ERROR: JSC_MISSING_PROVIDE_ERROR. required "clojure.core.async" namespace never provided at /home/jldupont/workspace/$someproject/target/cljsbuild-compiler-0/domain2/main.js line 4 : 0
I've got the following project.clj file:
(defproject $someproject "0.1"
:description "some project..."
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/clojurescript "0.0-2030"]
[org.clojure/core.async "0.1.267.0-0d7780-alpha"]
]
:plugins [[lein-cljsbuild "0.3.2"]]
:cljsbuild {
:builds [{:id "domain2"
:source-paths ["src/cljs/model2/domain"]
:compiler {:output-to "src/assets/js/model2/domain/domain2.js"
:optimizations :advanced
:pretty-print true}
}
]
}
)
Everytime I use lein cljsbuild auto I get the error quoted above.
Please help!
Update
I've looked in my ~/.m2 directory and the dependencies ( in this case core.async ) are present.
Update 2
It would appear that it is the Google Closure Compiler that spews out this error message. Not sure how to provide it a path to the dependencies...
As mentioned in my comment above: if you want to use core.async with ClojureScript you have to require the namespace cljs.core.async (instead of Clojure's clojure.core.async).

Lein uberjar fails on simple '-main' usage, but perhaps I don't understand all it's doing?

I've created a simple example using:
%> lein new lein-check
I've only modified the code so that it now has a 'main':
(defproject lein-check "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"}
:main "lein-check.core"
:dependencies [[org.clojure/clojure "1.4.0"]])
(ns lein-check.core
(:gen-class))
(defn -main
"I don't do a whole lot."
[& args]
(println "Hello, World!"))
But the first time I run lein uberjar even after a clean I get this:
Compiling lein-check.core
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to clojure.lang.Symbol
at clojure.core$find_ns.invoke(core.clj:3659)
at clojure.core$load_one.invoke(core.clj:5228)
at clojure.core$compile$fn__4895.invoke(core.clj:5426)
at clojure.core$compile.invoke(core.clj:5425)
at user$eval7.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6511)
at clojure.lang.Compiler.eval(Compiler.java:6501)
at clojure.lang.Compiler.eval(Compiler.java:6477)
at clojure.core$eval.invoke(core.clj:2797)
at clojure.main$eval_opt.invoke(main.clj:297)
at clojure.main$initialize.invoke(main.clj:316)
at clojure.main$null_opt.invoke(main.clj:349)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Compilation failed: Subprocess failed
Running a follow up uberjar though successfully creates the jars:
Created ....\lein-check-0.1.0-SNAPSHOT.jar
Including lein-check-0.1.0-SNAPSHOT.jar
Including clojure-1.4.0.jar
Created ....\lein-check-0.1.0-SNAPSHOT-standalone.jar
Is uberjar sometimes running the main after a completion? Is it supposed to do that? I'm not quite sure if this is a user error, a lein bug or a clojure bug.
The problem is in the line
:main "lein-check.core"
It should be
:main lein-check.core
You're using a string instead of a symbol.
Well it turns out that the Lein Sample Project show the :main as a symbol and not a string. Once this was updated then running lein uberjar works as expected.
This line in particular:
:main "lein-check.core"
changed to:
:main 'lein-check.core