Use plugins specified in profile.clj - clojure

I added some plugins to my profile.clj. When I start a new repl they are downloaded correctly to my .m2/repository directory, but I'm unable to (use '...) them, because this is throwing a FileNotFoundException. So how can I use these plugins in a default repl outside of a project?
Win 7
clojure 1.7
leiningen 2.5.3
jdk1.8.0_25
user=> (use 'hiccup.core)
FileNotFoundException Could not locate hiccup/core...
Same with fresh downloaded Incanter 1.9.0
I know that there're a couple of questions with this error, but all in the context of projects, not for a default repl. Or can I only use plugins in a project repl?
Thanks in advance!
Here my profiles.clj
{:user
{
:java-cmd "C:\\Program Files\\Java\\jdk1.8.0_25\\bin\\java.exe"
:plugins [
[cider/cider-nrepl "0.8.1"]
[incanter "1.9.0"]
[hiccup "1.0.5"]
]
}
}

you should probably add hiccup (and incanter) to :dependencies section
{:user
{
:java-cmd "C:\\Program Files\\Java\\jdk1.8.0_25\\bin\\java.exe"
:plugins [
[cider/cider-nrepl "0.8.1"]
]
:dependencies [
[incanter "1.9.0"]
[hiccup "1.0.5"]
]
}
}
also, i guess you should better add specific libraries to project.clj for every project that requires them, rather than adding them to global deps.

Related

Leiningen wont exclude namespaces from uberjar

I have a project where I want certain parts of the code to be able to run on a local environment, and other parts which depend on libraries that only run on a remote environment. E.g.
src/app/core.clj <- can run anywhere
src/app/sandbox/remote_only.clj <- depnds on libs that only function in remote environ
where src/app/core.clj is
(ns app.core
(:gen-class))
(defn -main [] (println "Hello, World!"))
and src/app/sandbox/remote_only.clj is
(ns app.sandbox.remote-only
(:require
[uncomplicate.commons.core :refer [with-release]]
[uncomplicate.neanderthal
[native :refer [dv dge]]
[core :refer [mv mv!]]]))
I want to be able to uberjar and run the code located in core.clj on my local machine without pulling in remote_only.clj which will cause the program to fail locally. According to the docs, Leiningen should be able to accomplish this using profiles and uberjar exclusions e.g.:
(defproject app "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.10.1"]]
:profiles {:uberjar {:main app.core
:init-ns app.core
:aot :all}
:remote {:init-ns app.sandbox.remote_only
:dependencies [[uncomplicate/neanderthal "0.43.1"]]}} ; these deps will fail locally
:uberjar-exclusions [#".*sandbox.*"]
:repl-options {:init-ns app.core})
compiling the uberjar here will result in:
❯ lein uberjar
Compiling app.core
Compiling app.sandbox.remote-only
Syntax error macroexpanding at (remote_only.clj:1:1).
Execution error (FileNotFoundException) at app.sandbox.remote-only/loading (remote_only.clj:1).
Could not locate uncomplicate/commons/core__init.class, uncomplicate/commons/core.clj or uncomplicate/commons/core.cljc on classpath.
So, explicitly its trying to compile the class that was specifically excluded.
I thought that this kind of problem could be avoided by removing the :all tag from :aot compilation. E.g.:
(defproject app "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.10.1"]]
:profiles {:uberjar {:main app.core
:init-ns app.core
:aot [app.core]}
:remote {:init-ns app.sandbox.remote_only
:dependencies [[uncomplicate/neanderthal "0.43.1"]]}} ; these deps will fail locally
:uberjar-exclusions [#".*sandbox.*"]
:repl-options {:init-ns app.core})
which causes other problems:
❯ lein uberjar
Compiling app.core
Created /Users/warrenronsiek/Projects/app/target/app-0.1.0-SNAPSHOT.jar
Created /Users/warrenronsiek/Projects/app/target/app-0.1.0-SNAPSHOT-standalone.jar
~/Projects/app 5s 15:47:37
❯ java -jar ./target/app-0.1.0-SNAPSHOT.jar
Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/Var
I've tried playing around with all kinds of :exclusions, :jar-exclusions and regexes. Variations of this question have been asked multiple times (1, 2) Nothing works.
How do I get Leiningen to compile uberjars and ignore the specified file(s)?
You are on the right track with changing :aot :all to :aot [app.core] but when you tried to run the JAR, you are running the library version instead of the whole application version:
java -jar ./target/app-0.1.0-SNAPSHOT.jar
That doesn't include Clojure or any dependencies. You want:
java -jar ./target/app-0.1.0-SNAPSHOT-standalone.jar
I haven't tried this particular setup with the "exclusions" features.
One workaround would be to create sub-projects for the "local" & "remote" parts of your app, which could then be used by a higher-level "total" project.
app
app-local
app-remote
where each of the 3 is a separate Lein project. app-local and app-remote could be developed in isolation. The top-level app project then uses has the 2 sub-projects as dependencies (and therefore only works in the remote/full environment).
The Lein feature checkouts allows you to develop in all 3 repos simultaneously, which is a huge help. It is much faster than the alternative of using lein install, which is slow, manual, repetitive, and error-prone.
P.S. Did you experiment with using lein jar instead of lein uberjar?

Very slow resource loading time with compojure route/resources and ring

Disclaimer: I am very new to clojure.
I am suddenly running into a issue where loading my clojurescript app takes over 15 seconds just to load all of the library code. A second project, set up the same way, is not having these issues.
CLJS build:
:cljsbuild {:builds [{:id "dev"
:source-paths ["src/cljs"]
:compiler {:output-to "resources/public/app/js/app.js"
:output-dir "resources/public/app/js/out"
:optimizations :none
:source-map true}}]}
handler.clj
(GET "/" [] (resource-response "index.html" {:root "public/app"}))
(route/resources "/" {:root "public/app"})
(route/not-found "Not Found"))
My first thought is, that it somehow re-compiles everything every time I access the page, but the file timestamps of unchanged libraries didn't change.
Second thought was, that it is probably because of cache killing in my browser, but even after allowing cache through the developer tools, file loading time is still snailspeed.
Third thought was the compojure version difference between the 2 projects, but even after upgrading the 2nd project to latest, or downgrading 1st project to previous version, the issue still persists.
When monitoring, I also noticed the java process to jump to 350% CPU on page access.
I tried to revert all changes I made but can't figure out where the problem is. Being very new to clojure and clojurescript, I am out of ideas. I obviously can't wait 15 seconds with every page load just to see a message in the console.
/ EDIT:
Project.clj
(defproject picky "0.1.0-SNAPSHOT"
:description "project"
:url "http://example.com/FIXME"
:source-paths ["src/clj"]
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/tools.reader "0.8.2"]
[org.clojure/clojurescript "0.0-2371"]
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
[ring/ring-core "1.3.1"]
[ring/ring-json "0.3.1"]
[compojure "1.2.1"]
[korma "0.4.0"]
[org.postgresql/postgresql "9.2-1002-jdbc4"]
[com.cemerick/friend "0.2.1"]
[lobos "1.0.0-beta3"]
[cljs-http "0.1.20"]
[secretary "1.2.1"]
[om "0.3.6"]
[com.facebook/react "0.8.0.1"]
[hiccup "1.0.5"]]
:plugins [[lein-cljsbuild "1.0.3"]
[lein-ring "0.8.13"]
[lein-pdo "0.1.1"]]
:aliases {"up" ["pdo" "cljsbuild" "auto" "dev," "ring" "server-headless"]}
:ring {:handler myapp.handler/app}
:profiles
{:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
[ring-mock "0.1.5"]]}}
:cljsbuild {:builds [{:id "dev"
:source-paths ["src/cljs"]
:compiler {:output-to "resources/public/js/app.js"
:output-dir "resources/public/js/out"
:optimizations :none
:source-map true}}]}
Middlewares are wrap-json-body and wrap-json-response, although I tried already disabling both.
I found the culprit of this huge performance loss. After a ton of debugging I found out that the only difference between project 1 and project 2 is the resources folder.
Project 1 includes a entire frontend project. A lot of files through bower, scss, compiled css, compiled cljs and so on. Everything you need for good frontend development. In total 10506 files.
Project 2 was a test project including a few HTML, javascript and compiled cljs files. 142 files in total.
For testing, I moved some files out of the resources folder and ta-daa, file load is down to a few milliseconds. Move the files back into the resources folder, performance get tanked up.
I am going to file a bug report at the compojure project. Might be something they weren't aware of yet.

Clojure REPL Import trouble-shooting

Okay. I'm trying to muck about with twitter4j inside a Clojure REPL, provided by Leiningen. I've specified twitter4j as a build dependency:
(defproject testproject "0.1.0-SNAPSHOT"
:description "Tryin stuff"
:repositories {
"twitter4j" "http://twitter4j.org/maven2"
}
:dependencies [[org.clojure/clojure "1.5.1"]
[compojure "1.1.6"]
[org.twitter4j/twitter4j-core "3.0.5"]
[org.twitter4j/twitter4j-stream "3.0.5"]]
:plugins [[lein-ring "0.8.8"]]
:ring {:handler testproject.core/app}
:profiles {:dev
{:dependencies [[javax.servlet/servlet-api "2.5"]
[ring-mock "0.1.5"]]}})
So far, so good. lein deps downloads everything without complaint into the default repo in ~/.m2. Awesome. I fire up the REPL, and I get this and only this:
user=> (import '(org.twitter4j.conf ConfigurationBuilder))
ClassNotFoundException org.twitter4j.conf.ConfigurationBuilder java.net.URLClassLoader$1.run (URLClassLoader.java:202)
The twitter4j jars are all present and accounted for, in ~/.m2/org/twitter4j/twitter4j-core/3.0.5/. Is there... something I don't get about importing Java classes? Some extra config I need to provide?
Try this (the proper package name):
user=> (import '(twitter4j.conf ConfigurationBuilder))

How do I force Leningen to use use a particular version of swank-clojure?

Here's my project.clj:
(defproject hello-world "1.0.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.3.0"]]
:dev-dependencies [[swank-clojure "1.5.0-SNAPSHOT"]]
:plugins [[lein-swank "1.4.3"]])
Leiningen downloads swank-clojure 1.4.0 every time I run lein swank.
(I'm using leiningen 1.7.0)
I don't think you need both the :plugins swank and the :dev-dependencies one.
try with just the dev-dependencies
Assuming you want to always use the same version of swank-clojure (which is also lein-swank),
you can run (for leiningen 1.x):
lein plugin install swank-clojure "1.5.0-SNAPSHOT"
For leiningen 2.x you can add the following to :plugins in the profile.clj file of your lein directory:
[lein-swank "1.5.0-SNAPSHOT"]
and the plugin will be usable from all of your leiningen projects without having to specify the requirement in the project file.

How to Resolve Clojure Cake Compile Error

[Mea Culpa I pointed to Clojure 1.3, not Clojure 1.3.0.]
I just downloaded the latest Clojure jar file, 1.3.0. I have a simple cake project, which is now throwing a missing artifact error
1 required artifact is missing.
for artifact:
org.apache.maven:super-pom:jar:2.0
What do I need to add to my project.clj file
(defproject repl-test "0.0.1-SNAPSHOT"
:description "TODO: add summary of your project"
:dependencies [[org.clojure/clojure "1.3"]
[org.clojure/clojure-contrib "1.2.0"]
[clojure-csv/clojure-csv "1.2.4"]
[org.clojure/tools.cli "0.1.0"]
[clj-http "0.1.3"]]
:repositories {"clojure-snapshots" "http://build.clojure.org/snapshots"}
:main repl-test)
or what do I need to build to fetch this missing artifact?
I have made sure the clojure-1.3.0.jar file is installed.
If this is a POM problem, I'm not sure what command to run to install the artifact.
Replace [org.clojure/clojure "1.3"] with [org.clojure/clojure "1.3.0"] then this should work.