Leiningen compile does nothing - clojure

(leiningen v 2.5.1)
Leiningen compile seems to be doing absolutely nothing, even with a new project. My steps are
lein new default foo
cd foo
lein compile
ls | grep target # nada
lein jar # does create a target, but with an empty .jar. Still no .class files
EDIT
I also tried with the :all :aot flags, still no dice.
What next?

You need to add :aot :all into your project.clj (Note, you have it vice-versa in your edit). After that compile task will compile all your namespaces. You can also name only those namespaces you want to compile.
As a side note, also in resulting jar the Clojure namespaces does not need to be in compiled form. This is the role of :aot key to control which namespaces will get compiled.

Have a look in your project.clj file. You will see there is very little there. The lein command your using to setup the project is a bare minimum definition. It has very little in it. You might do better with the 'app' template to start with. You also need to look at the lein documentation to see what goes into the project.clj file. Google for some lein templates to see what other templates are available. I would then select one and an initial simple project to play with.
Note that you don't need to run lein compile to just get started with clojure and writing some codes/expressions to play with - run lein repl instead.

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.

How to compile and import Java class with lein-figwheel?

I added :java-source-paths ["src/java"] to my project.clj, lein uberjar works but when running lein figwheel I get the following error:
Figwheel: Cutting some fruit, just a sec ...
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
java.lang.ClassNotFoundException: projectc.java.gcloud.DataStore, compiling:(projectc/gcloud/datastore.clj:1:1)
I added this to the ':uberjar` section
:prep-tasks ["javac" "compile" ["cljsbuild" "once" "min"]]
Any clues to how to solve this?
When Figwheel (and the ClojureScript compiler) compiles your code, it will process all clj files that it is given, to compile macros that are in clj files. It looks like Figwheel is trying to compile a file which is using a class which isn't on the Classpath? Is it possible to include that class, or exclude the Clojure file from the Figwheel compilation? Perhaps try building that Java project as a JAR and including it as a dependency as a test?
It's a little hard to tell with not very much information, this issue also looks like it might be relevant?

How do I use the Clojure `use` function in leiningen?

I am very new to both Clojure and Leiningen. I have installed Clojure on Windows at C:\clojure-1.5.1 and leiningen-win-installer beta1 at C:\.lein\bin.
Now I am trying the example from Eric Rochester's book. I have included dependent libraries for Incanter in project.clj and also using dep.
How do I use the command (use 'incanter.core)? I am getting 'use' is not recognized as an internal or external command. In addition, how do I use lein commands at user=>?
Edit - I forgot "lein deps" until I saw Mars's answer
Before you start lein repl, you have to make the project (with "lein new getting-data" or whatever is in the book).
That makes a new directory, and in that directory you find and edit "project.clj" to include the dependencies (as shown in book).
cd into the directory that project.clj is in and run "lein deps" from the dos/powershell prompt.
THEN when you run lein repl, from within that same directory, at the user=> prompt, do
(use 'incanter.core)
and it will come back with "nil" and you'll be running. You might want to first run some examples from the leiningen page to get more of a feel for lein. You always type clojure commands at the "user=>" prompt, not at the "c:....>" prompt.
There's a bit of subtlety in Leiningen project.clj's. I haven't found an easy introduction. Levin Magruder's advice will no doubt get you started. The basic idea is that once the project file is set up correctly, lein deps will go out and find the libraries you need, and put them in a place where lein repl can find them. Then use will work for the libraries that have been downloaded. For more info, study of the detailed comments project.clj sample file may be helpful. (Not part of the answer to this question, but if you're having problems with use, you're likely to get tripped up by ns and filenames soon (I was): I recommend Colin Jones' introduction to ns and its options.)

FileNotFoundException when I create a new leiningen project

I just installed leiningen and am following the tutorial on how to start. I typed
lein new my-stuff and then corrected the project.clj file as per the instructions. Then I type lein repl and it pulls up the repl fine.
The next step is to type
(require 'my-stuff.core)
This is where I get
FileNotFoundException Could not locate my_stuff/core__init.class or my_stuff/core.clj on classpath: clojure.lang.RT.load (TR.java:432)
I have tried looking at my classpath, but everything looks alright.
lein classpath
C:\Users\Sarah\leiningen\test;C:\Users\Sarah\leiningen\src;C:Users\Sarah\leiningen\dev-resources;C:\Useres\Sarah\leiningen\resources;C:\Users\Sarah\leiningen\target\classes;C:\Useres\Sarah\.m2\repository\org\clojure\clojure\1.4.0\clojure-1.4.0.jar
Any help would be great!
I suspect that the problem here is stemming from your choice of project name. Although you can create Clojure namespaces with hyphens in them, the corresponding physical files and directories need to have the hyphen replaced with an underscore.
As you are just experimenting, the easiest thing for you to do would be to start again with a different project name: try lein new mystuff for example.
If you want to press on with my-stuff then try renaming the src\my-stuff directory to src\my_stuff and doing the same for test\my-stuff if it exists.
To be honest, I'm a little surprised that Leiningen has got this wrong, so there may be something else at work here, or you might just be using an old version of Leiningen.

Clojure load files

I'm trying to set up a simple clojure project, and I'm not sure how to load files between the project. I'm sure that the answer is in the documentation, but I can't find a simple answer any where and I'm not sure where to look.
Essentially, my directory looks like this:
Clojure/
clojure/
clojure.jar
other clojure files
clojure-contrib/
clojure-contrib.jar
other contrib files
project/
main.clj
utils.clj
And I want main.clj to be something like this:
(ns project.main
(:require project.utils))
(greet)
and utils.clj to be something like this:
(ns project.utils)
(defn greet [] (println "Hello, World!"))
But that fails with:
Exception in thread "main" java.io.FileNotFoundException: Could not locate project/utils__init.class or project/utils.clj on classpath: (main.clj:1)
When I attempt to run it. My classpath includes the top Clojure/ directory and both jars. I also tried putting the project/ directory in the classpath as well, with no luck.
How do you set up a simple clojure project?
You don't mention what your environment is (i.e. Emacs/SLIME/Swank, vim/Vimclojure), so I'm going to assume you are trying to invoke it from the command line.
You need to have your Clojure/ project directory in the classpath:
java -cp path/to/clojure.jar:path/to/clojure-contrib.jar:path/to/Clojure ...
Make sure to check that paths are correct relative to current working directory. It needs to point to the root of your namespace (i.e. if running in Clojure/, the path is .).
In fact, your project layout Works On My Machine(tm), with the exception that I have use instead of require (but you should've got a different error anyway if you got to the point when Clojure could find all your files).
This answer I posted to another question should hopefully give you an idea of how your filenames should relate to namespace names for things to work. However, since your question is "how to set up a simple Clojure project", the following is a better start:
Go to GitHub and grab Leiningen.
Follow the instructions in the README. You'll end up doing something like
$ lein new my-project
$ cd my-project
# ... edit project.clj ...
$ lein deps
Hack away! You'll need to put your files in the correct places. That will mean putting your source files in the directory tree rooted at my-project/src, with your core namespace most likely residing at my-project/src/my_project/core.clj. But really, I've explained all the details in the answer linked to above, so please read it (and do leave a comment if I missed something). :-)
Leiningen will take care of the basic project layout and setting up the classpath for a REPL / swank / nailgun for you (if you haven't yet come across the latter two, you will soon -- but that's a separate topic, the swank part of which I have covered to a certain degree e.g. in this SO answer), so hopefully you'll never need to deal with the java -cp ... nonsense by hand. (The swank-related answer I linked to in the last parenthetical remark has details on how to set up swank with the correct classpath from within Emacs.)