Dependencies in profiles.clj aren't loaded in lein repl - clojure

.lein/profiles.clj has dependencies as,
{:user {}
:repl {:dependencies [[org.clojure/clojure "1.4.0"]
[ring/ring "1.1.6"]]
}}
in repl
(require 'ring.adapter.jetty)
throws,
java.io.FileNotFoundException: Could not locate ring/adapter/jetty__init.class or ring/adapter/jetty.clj on classpath: (NO_SOURCE_FILE:0)
This means, ring dependency is not loaded in repl shell. Any mistakes?

Firstly, I would recommend reading https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md as I'm not sure you are using profiles correctly. In particular, at the end it shows a way of debugging your profiles, which will show you what is going on.
Secondly, I'm not sure about "there is no project - I am running it from bash shell". If your loading jetty and using ring, you will also need code which sets handlers, routes and probably middleware. this means code files, which means a project tree. Create a basic project with lein new and run from the root of that project.
However, if you really do need to do it as you say, I would suggest you just do
{:user {:dependencies [[....]]}} as your profiles.clj as I suspect that what is happening is that lein is not loading your :repl profile. You could also try running lein with the explicit profile i.e. lein with-profile +repl repl

Related

Could not locate clojure/data/json: How do I get my REPL to see this (and similar) dependencies

I am using lein repl without a project so there is no project.clj.
I am running Leiningen 2.8.1 on Java 1.8.0_191 OpenJDK 64-Bit Server VM.
When I require a Clojure dependency that I assume should just work - like clojure.data.json - I notice that it is not in my .m2 directory. Is that why I am getting a FileNotFoundException Could not locate clojure/data/json__init.class or clojure/data/js
on.clj on classpath? I can't find my other Clojure dependencies there either so I don't know where they reside and if this dependancy should be in .m2 or not.
I understand the error message but without knowing its location or even knowing how to properly add it to the CLASSPATH for the REPL to see it, I remain stuck.
Is this a dependency that I still need to install? If so, how do I install it without going through a project?
I don't understand the JVM as I am new to it, so add a little extra information in your answer.
I have looked at this, this, this, this and this. I don't know if I am overlooking anything so your help will really be appreciated.
I am using lein run without a project so there is no project.clj.
If you're using Leiningen, this'll be much easier if you create a project.clj file that declares your dependencies. Leiningen will read project.clj and handle fetching any missing dependencies to your local Maven repository, and add them to your classpath when you start your REPL/application. (lein run doesn't work for me in a directory without a project.clj; I get an error: No :main namespace specified in project.clj.. Did you mean lein repl?)
When I require a Clojure dependency that I assume should just work - like clojure.data.json - I notice that it is not in my .m2 directory.
clojure.data.json doesn't ship with Clojure — it's a separate dependency that must be fetched and added to your classpath in order to use it. The classpath tells the JVM where to look when it loads class files. Leiningen will do both of these things for you if you declare the dependency in project.clj:
:dependencies [[org.clojure/clojure "1.10.0"]
[org.clojure/data.json "0.2.6"]]
You can also use the lein deps command if you only want to fetch dependencies.
You can create a new/blank Leiningen project with lein new project_name_goes_here. It will have a project.clj with a few boilerplate entries and a :dependencies key where you can declare dependencies.
I understand the error message but without knowing its location or even knowing how to properly add it to the CLASSPATH for the REPL to see it, I remain stuck. Is this a dependency that I still need to install? If so, how do I install it without going through a project?
You could manually download it from the internet, then manually add its path to your classpath, but if you're already using Leiningen it's much easier to add a line to a project.clj file and have Leiningen handle this for you.
If using a project.clj file w/Leiningen isn't an option, there are other ways to use Clojure and resolve dependencies/build a classpath at runtime. Boot accommodates this workflow, you can use Leiningen like this with a little added effort, as well as the newer tools.deps tooling. There are examples of each in this ClojureVerse thread, but note that some of these approaches are doing essentially the same thing as declaring the dependency in a file — instead declaring them as CLI arguments.
For example, using Clojure CLI tooling:
$ clj -Sdeps "{:deps {org.clojure/data.json {:mvn/version \"0.2.6\"}}}"
Clojure 1.9.0
user=> (require '[clojure.data.json :as json])
nil
user=> (json/write-str {:foo "bar"})
"{\"foo\":\"bar\"}"
user=> (System/getProperty "java.class.path")
"src:
/Users/me/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar:
/Users/me/.m2/repository/org/clojure/data.json/0.2.6/data.json-0.2.6.jar:
/Users/me/.m2/repository/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143.jar:
/Users/me/.m2/repository/org/clojure/core.specs.alpha/0.1.24/core.specs.alpha-0.1.24.jar"
You could create a deps.edn file containing {:deps {org.clojure/data.json {:mvn/version \"0.2.6\"}}} in the same directory, and clj would read that, resolve the dependencies if necessary, and build the classpath accordingly.
This is a great opportunity to use lein try. Once you add it to your ~/.lein/profiles.clj, you'd simply run: lein try org.clojure/data.json and you'll be greeted with a running REPL with that dependency just a require away.

Can I start Gorilla REPL from an uberjar?

I play with this great Gorilla REPL powered project ( https://bitbucket.org/probprog/anglican-examples/ to be specific), and want to use it under certain restricted circumstances.
Is there a way to produce an uberjar that can be started using only a JVM?
Well, I know how to create an uberjar for this project, but can I start a Gorilla REPL from it? If not what do I have to add and how do I start it?
EDITED Note on Juraj's answer:
I added a start file src/gorillaproxy/gorillaproxy.clj with the following content:
(ns gorillaproxy.gorillaproxy
(:use [gorilla-repl.core :only [run-gorilla-server]])
(:gen-class))
(defn -main
[& args]
(run-gorilla-server {:port 8990}))
Then I added [gorilla-repl "0.4.0"] to the dependency list (in project.clj), and the line
:main gorillaproxy.gorillaproxy
In that way the uberjar started the Gorilla REPL, and when I put the worksheets (and data, resources, .. if needed) into the same directory, everything worked fine.
Gorilla is typically run via the lein-gorilla plugin and thus isn't a part of an uberjar.
If you really want to create a bundle containing gorilla repl dependencies, then you need to add it this capability manually to your project.
The question is why would you want to do that.
Do you want to distribute these samples to somebody else? If that's the case, you'll still need to have all those worksheets in the current directory from where your uberjar is run because that's how gorilla repl discovers worksheets.
You can look at lein-gorilla source code to see how gorilla repl can be started.
I'd then at the same code to your project (create new src/core.clj file or whatever) and configure it in your project.clj as :main.
You'll also need to add gorilla-repl as a dependency to your project.clj
Notice however, that you'll need to run that uberjar from a directory where your anglican worksheets are (or a parent directory of such a directory).

clojure classpath(?) troubles loading code and dependencies with leiningen

I'm a Clojure and JVM beginner, and the build tools are a bit confusing to me, so forgive the stupidity I'm about to carry out. I don't actually know what a "classpath" is... I just want a Lisp with lots of libraries!
But I'm trying to do a write a simple little bit of text-mining code in Clojure, and I don't seem to be able to get things working.
There are two problems, and I think they're related, both probably to this classpath thing from javaland that none of the introductory Clojure books seem to explain.
I started the project with lein new and my project.clj has the following dependencies:
:dependencies [[org.clojure/clojure "1.6.0"]
[clj-fuzzy "0.1.8"]
[snowball-stemmer "0.1.0"]
[net.mikera/core.matrix "0.50.0"]])
and the relevant ns call from my core.clj is as follows:
(ns blabber.core
(:require
[clojure.string :refer [lower-case split]]
[clojure.walk :refer [keywordize-keys]]))
My directory structure is the default setup leiningen uses for a new library.
First problem:
I gather from this prior SO that if things are set up right, I shouldn't need to call (load-file "src/blabber/core.clj") in the repl before calling (use 'blabber.core) in order to get at code I just wrote. (I'm firing up the lein repl from the src/blabber directory in bash). But when I fire up the repl, use fails unless I call load-file first. So does that mean my classpath is set up wrong somehow? And how does one fix such a thing?
Second problem:
Ok, so now I'm trying to actually use core.matrix. First line of my core.clj changed to:
(ns blabber.core
(:require
[clojure.string :refer [lower-case split]]
[clojure.walk :refer [keywordize-keys]]
[clojure.core.matrix :refer [dataset]]))
When I first started the repl with this project.clj but without the :require to core.matrix, leiningen happily fetched core.matrix: Retrieving net/mikera/core.matrix/0.50.0/core.matrix-0.50.0.jar from clojars
However, after including the :require to core.matrix in the actual code and starting up the repl again, at the repl I call (load-file "src/blabber/core.clj"), and get the following error:
CompilerException java.io.FileNotFoundException: Could not locate clojure/core/matrix__init.class or clojure/core/matrix.clj on classpath: , compiling:(/Users/pauliglot/github/blabber/src/blabber/core.clj:1:1)
I'm using Leiningen 2.5.1 on Java 1.8.0_45. And I'm just following the getting started guide for core.matrix.
So what happened? Why can't the JVM find any of my stuff? Save me? Thanks!
If it helps, here's a dump of the output of lein classpath
/Users/pauliglot/github/blabber/test:/Users/pauliglot/github/blabber/src:/Users/pauliglot/github/blabber/dev-resources:/Users/pauliglot/github/blabber/resources:/Users/pauliglot/github/blabber/target/classes:/Users/pauliglot/.m2/repository/clj-fuzzy/clj-fuzzy/0.1.8/clj-fuzzy-0.1.8.jar:/Users/pauliglot/.m2/repository/snowball-stemmer/snowball-stemmer/0.1.0/snowball-stemmer-0.1.0.jar:/Users/pauliglot/.m2/repository/org/clojure/tools.macro/0.1.5/tools.macro-0.1.5.jar:/Users/pauliglot/.m2/repository/clojure-complete/clojure-complete/0.2.3/clojure-complete-0.2.3.jar:/Users/pauliglot/.m2/repository/org/clojure/google-closure-library-third-party/0.0-20140226-71326067/google-closure-library-third-party-0.0-20140226-71326067.jar:/Users/pauliglot/.m2/repository/com/google/protobuf/protobuf-java/2.4.1/protobuf-java-2.4.1.jar:/Users/pauliglot/.m2/repository/org/clojure/google-closure-library/0.0-20140226-71326067/google-closure-library-0.0-20140226-71326067.jar:/Users/pauliglot/.m2/repository/org/mozilla/rhino/1.7R4/rhino-1.7R4.jar:/Users/pauliglot/.m2/repository/org/json/json/20090211/json-20090211.jar:/Users/pauliglot/.m2/repository/net/mikera/core.matrix/0.50.0/core.matrix-0.50.0.jar:/Users/pauliglot/.m2/repository/com/google/javascript/closure-compiler/v20131014/closure-compiler-v20131014.jar:/Users/pauliglot/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar:/Users/pauliglot/.m2/repository/org/clojure/clojurescript/0.0-2202/clojurescript-0.0-2202.jar:/Users/pauliglot/.m2/repository/args4j/args4j/2.0.16/args4j-2.0.16.jar:/Users/pauliglot/.m2/repository/org/clojure/tools.nrepl/0.2.6/tools.nrepl-0.2.6.jar:/Users/pauliglot/.m2/repository/com/google/guava/guava/15.0/guava-15.0.jar:/Users/pauliglot/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar:/Users/pauliglot/.m2/repository/org/clojure/tools.reader/0.8.3/tools.reader-0.8.3.jar:/Users/pauliglot/.m2/repository/org/clojure/data.json/0.2.3/data.json-0.2.3.jar
Edit
Here's the directory tree:
| blabber
|-doc
|-resources
|-src
|---blabber
|-target
|---classes
|-----META-INF
|-------maven
|---------blabber
|-----------blabber
|---stale
|-test
and all my code is in blabber/src/blabber/core.clj
A classpath is a Java concept; Leiningen should set up the classpath correctly. What I suspect is that there's a mismatch between the directories, filenames, or namespace declarations. The file path should be <name passed to 'lein new'>/src/blabber/core.clj. It wasn't clear from what you wrote whether that's the case. Try running lein deps first, too, but you shouldn't need to do that. This and lein repl are usually run from the directory, i.e. the project root directory. You might need :source-paths or :main in project.clj, but I don't think so.
(use 'clojure.core.matrix) should work. Works for me, e.g. with
(defproject blabber "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.8.0"]
[net.mikera/core.matrix "0.50.0"]]).

leinigen repl with profile

This question is a follow up to How does one pre-load a clojure file in the leiningen repl?.
My ~/.lein/profiles.clj looks as follows:
{
:user {:source-paths ["C:/Users/username/.lein/src"] }
}
My ~/.lein/src/user.clj might look as follows:
(ns user)
(println "user file loaded")
When I run lein repl within a folder containing a project.clj, then the user.clj file is executed, but when I run lein repl from another folder it doesn't load my user profile. Is there a workaround for this or is this behavior by design? In fact, I know that Leinigen is indeed loading my profile.clj (even when there is no project.clj) because there are also other things inside (taken from the excellent pimp my repl article). Leinigen is just having problems with my additional source-paths setting.
One other question related to this is the fact that I need to specify the full path of the folder for my user.clj file : "C:/Users/username/.lein/src". When I change that to "~/.lein/src" leiningen fails to load my file.
It sounds like you just want some code loaded for your lein repl sessions. This is done with the :init key of the :repl-options in your profiles.clj. You can load-file other files in init if you want to organize in that fashion.
{:user
{:repl-options
{:init (load-file "path-to-file/user.clj")}
...}}
Note: If you are using Windows-style path delimiters /, you'll need to escape them //.

upgrading lein project from clojure 1.2.1 to 1.3.0-beta1

I have a leiningen project that uses clojure 1.2.1. I would like to add a dependency to a package that requires clojure 1.3.0-beta1. So I decided to upgrade my project to the newer version.
To be honest I was not sure what that involved but I did the following..
In my project.clj I changed my dependency from
[org.clojure/clojure "1.2.1] to [org.clojure/clojure "1.3.0"]
I use swank so I changed my swank clojure dependency to [swank-clojure "1.3.2"].
I then ran
lein deps
Lastly I manually edited my /usr/bin/lein file to change the CLOJURE_JAR variable to point to the newer clojure jar.
When I start swank with 'lein swank'. It starts fine and I now get the following warning messages
like so..
Warning: default-javac-options not declared dynamic and thus is not dynamically rebindable, >but its name suggests otherwise. Please either indicate ^:dynamic default-javac-options or >change the name.
Which I think has to do with clojure 1.3.0.
I then fire up Aquamacs and run slime-connect. The REPL starts fine but when call clojure-version
if get "1.2.1".
; SLIME 20100404
user> (clojure-version)
"1.2.1"
Is there something else I need to do?
I think, that you need to add :exclusions list to swank-clojure specification, something like:
:dev-dependencies [[swank-clojure "1.3.2"
:exclusions [org.clojure/clojure]]]
although, I just checked my installation, and clojure 1.3 worked out of box. I think, that you just forgot to call lein clean before lein deps...