I am trying to go through the process of creating a jar file from a simple clojure file. Below is my clojure code:
(ns app.first (:gen-class))
(refer 'clojure.core)
(defn -main [& args] (println "this program worked!"))
I am using these instructions to create the jar file: http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips
I see the error "java.io.FileNotFoundException: Could not locate app/hello__init.class or app/hello.clj on classpath: (NO_SOURCE_FILE:0)" when I try to complete the (compile 'app.first) step.
The only difference between my attempt and the link is the name of my file (first.clj instead of hello.clj).
Can anyone see where I am going wrong? Or for that matter, all I want to do is learn how to create a jar from a clojure file, so if anyone knows of a better/easier way to do that, let me know.
It's better to use Leiningen for such tasks - it allows to maintain dependencies, and packs all necessary components into jar file
I'm rusty on this, but I heard about other people with similar problems.
I think it's helpful to remember that the classpath you indicate points to the root of your class tree, and package names end up creating subdirectories within that tree. Awkwardly stated, but I hope you get the idea. Thus, I think you need to do some kind of gymnastics with creating directories to match the "app.first" -> "/app/first" hierarchy.
Sorry, that's as close as I come to a sensible and useful answer. Hope this helps you.
EDIT:
The Prime Directive of Computer Science: It only works if you do everything right! I spent almost 10 minutes fiddling with this but was finally successful.
Here's what I needed to do to get your program to compile:
created a directory app, and within that, first.clj with your code.
checked for the *compile-path* by doing (pr *compile-path) within Clojure. It said "classes".
created a second directory classes parallel to app.
in the shell, did export CLASSPATH=.:./classes
in Clojure, did (compile 'app.first)
... and I found a bunch of class files in classes. JARring those should be a snap.
I found it very helpful to run (doc compile) because that reminded me of the requirement to have a directory to satisfy the requirement for a *compile-path*.
Related
Suppose we wanted to write a cheating quine in clojure, we could do:
(ns cheating-quine)
... stuff here doesn't really matter ...
(println (slurp *file*))
Now, this does not work in Lein Figwheel because the value of file ends up being something like /tmp/form-init########.clj, and contains bootstrapping code of some sort.
Question: how can we get this "cheating" quine to work in clojurescript?
Note: the goal is NOT to write a quine. The goal is to write a cljs program which has access to the file it's defined in. This whole "cheating quine" thing is trying to explain the problem better then my previous failed attempt of
Clojure + Clojurescript: Macro to read code of current file
A cheating solution is to distribute the source code (e.g. put it in resources and serve it as a file) and compile a bootstrap to load and execute code, and get it to pull down your file, and in the file load the same file... that way it can do a HTTP request for the code that is currently running, and execute it. This is essentially how ClojureScript browser REPLs such as http://clojurescript.io/ work... They compile and execute incoming code on the fly. clojuresript.io is a good working example of ClojureScript bootstrapping if you are interested in it, but a word of caution, there is quite a lot going on so expect to invest quite some time :)
I have just begun playing with ClojureScript and I'd like to collect all CSS files into a single folder (out/css). I found leiningen-less and with the following config I get the compiled CSS files into the correct location:
:less {:source-paths ["src/less"]
:target-path "out/css"}
I can't find any documentation on how I can handle the ordinary CSS files (e.g. the file for resetting defaults, css/reset.css). Basically I want the equivalent of cp css/*css out/css.
I did find lein-resource but it does a bit more than I require (pass things through stencil) and more importantly it through an UnsupportedOperationException on my with what I thought would a be a valid configuration:
:resource {:resource-paths ["css" {:target-path "out/css"}]}
Please englighten me!
For your particular use case just rename reset.css to reset.less. less should be able to read CSS without problems.
For more advanced frontend tooling maybe consider adding something like make/grunt/etc. More complexity but more power & flexibility.
I think better and easy solution would be that you write a function that uses clojure.java.io library functions and integrate them with lein-less "compiler" fork, so this is my internal function proposal:
(defn your-fn[]
(remove-folder "./out") ;; => you have to do how to make that fn following io lib doc
(copy-folder "./css ./out") ;; ;; => you have to do how to make that fn following io lib doc
(run-compiler :javascript
{:project-root "your-project-root/"
:source-paths ["less"]
:target-path "out"})))
PS: note that you need to call this fn from your clojurescript compilation process, BTW I didn't know if there is a way for that :)
(Sorry this is so long. It's long to rule out misunderstandings, not because I want you to figure out what my question should be.)
I understand the basics of Clojure namespaces, and that the namespaces listed in my ns statements at the beginnings of files have to match locations of files in a directory hierarchy. I have figured out part of what Leiningen is doing automatically to set up search load, and part of what it is loading automatically, but ... it's still driving me crazy. The problem is that there are things that Leiningen seems to set up implicitly, that are also not well documented in the obvious places like the Leiningen tutorial and the sample project file. (Maybe the information is there, but I haven't found it/interpreted it.)
I've got things set up so that when I do lein repl, the main source files are loaded (popco.clj and acme.clj below), but loading other files causes trouble. I want to make the MWE as minimal possible, and the question short, but I want to make it clear that I am not asking simpler questions that have been answered already (e.g. this one).
Here's where source files are, with ns statements from the same files listed over on the right:
src/popco/sims/sim1/sim1propns.clj (ns popco.sims.sim1.sim1propns)
src/utils/general.clj (ns utils.general)
src/popco/core/acme.clj (ns popco.core.acme)
src/popco/core/popco.clj (ns popco.core.popco
[:use popco.core.acme]
[:import [popco.core.acme Propn Obj]]
(:gen-class)) ; not sure what this does yet
Here's the project.clj file:
(defproject popco-x "0.0.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.5.1"]]
:main popco.core.popco
:profiles {:dev {:dependencies []
:source-paths ["src"] }})
When I run lein repl, I see that I'm in the popco.core.popco namespace:
popco.core.popco=>
and I find that both functions and record types defined in acme.clj are available. I have learned (by trial and error) that ":main popco.core.popco" in project.clj is causing popco.clj to run, and that results in the the REPL being left in the popco.core.popco namespace. So far, so good.
Here are my questions:
What if I want to load src/utils/general.clj, or src/popco/sims/sim1/sim1propns.clj ? I can load them with load-file, but I'd like to use load in the REPL, and more importantly, I'd like to be able to require or use these source files from other source files. How can I reference the functions in general.clj from inside acme.clj, for example? I think the answer might be to add entries to the sequence after :source-paths in project.clj, but I'm confused about what should go there.
Feel free to recommend anything. Other directory structures, radical changes to project.clj, whatever.
Everything about your project structure and project.clj looks entirely normal.
What if I want to load src/utils/general.clj:
This is almost always done through a require or use expression. While it is possible to load a file with load-file this requires you to specify the path (relative to where you started the JVM) to the file. load loads it relative to the class-path though in practice these are almost never used when the files being loaded are part of the project. In that case you can simply require them.
I'd like to be able to require or use these source files from other source files:
The expected way of doing this is to put a (:require [popco.core.acme :as acme]) statement in the ns form at the top of the namespace that wants to use functions from that namespace.
How can I reference the functions in general.clj from inside acme.clj:
(ns popco.core.acme
(:require [utils.general :refer [function1 function2] :as general))
I think the answer might be to add entries to the sequence after :source-paths in project.clj:
You will most likely never need to put anything there. require and use are the appropriate tool for this. They will already be able to find all the files under /src/ because those files will be in the classpath when the leiningen starts java. You can see the class path used with the lein classpath function.
ps: You can also call require and use as functions (form the REPL for instance), though doing this in the ns form is generally preferred.
A question from an utter newcomer to clojure: What if I want to be able to start a clojure REPL from anywhere, for example because I just want to compute an exponent? How can I set up my system to do this? (I've deleted earlier links to not-quite-answers because they were cluttering up the question.) The Pomegranate documentation linked by #Jared314's answer below helped me see that I can do this:
~$ lein repl
...
user=> (use '[cemerick.pomegranate :only (add-dependencies)])
nil
user=> (add-dependencies :coordinates '[[org.clojure/math.numeric-tower "0.0.2"]])
{[org.clojure/clojure "1.3.0"] nil, [org.clojure/math.numeric-tower "0.0.2"] #{[org.clojure/clojure "1.3.0"]}}
user=> (use 'clojure.math.numeric-tower)
nil
user=> (expt 2 3)
8
Yay!
Now how can I make this happen every time I start the REPL, no matter what subdirectory I'm in?
I think I'm just ignorant of basic clojure setup. Sorry about that.
Second major edit:
I've figured out that if I use raw clojure without lein, I can execute commands on startup of the repl. For example, if the file .clojurerc contains the text (print "Yow!\n"), I can do this:
~$ java -cp /usr/local/lib/clojure-1.5.1/clojure-1.5.1.jar clojure.main -i .clojurerc -r
Clojure 1.5.1
Yow!
user=>
Can I do something like this with lein? Or maybe better yet, load clojure.math.numeric-tower automatically in clojure without using lein (since for simple command line experimentation, lein's startup is slower than starting clojure directly).
(It may seem as if I'm not trying to solve this on my own, but I that's not so. I have been doing web searches and experimenting, but I keep hitting brick walls. I'm starting to feel as if clojure is only intended for full-blown programming projects. I had assumed that it could be good for add-hoc experiments and calculations (as lisps traditionally are but Java is not). I'm not trying to incite arguments. I'm just frustrated. There ought to be a simple, well-known formula for doing what I'm trying to do.)
When you want external dependencies you will need either a new project, lein new testproject1, the lein-oneoff plugin, Pomegranate, a Leiningen profile :dependencies entry, or some specific IDE feature. (I know at least LightTable allows external dependencies in their Instarepl, so I assume you can do it in Emacs and CCW.)
It might be best to start with creating a new test project so you can see the project.clj layout. But, if you just want a one-off library in a repl, take a look at the instructions for Pomegranate's add-classpath command. Pomegranate is accessible by default in the lein repl, so their example should work without anything extra.
Edit:
From your updated question, it sounds like you want a persistent repl dependency. You can add [org.clojure/math.numeric-tower "0.0.2"] to your ~/.lein/profiles.clj profile file, under the :repl profile.
{:user {}
:repl {:dependencies [[org.clojure/math.numeric-tower "0.0.2"]]
:repl-options {:init (use 'clojure.math.numeric-tower)}}}
Then when you run lein repl:
(expt 2 3) ;=> 8
Looking at this question a few months later, I realized that I settled on a different solution, but never posted it. I now leave references to math.numeric-tower out of both .clojurerc and .lein/project.clj, since I don't need it for most Leiningen projects. And when I want to use Clojure for quick calculations, I start Clojure via a shell script without Leiningen to avoid slow startup. This is what's in the shell script:
#!/bin/sh
jars=/usr/local/lib/clojure-1.5.1/clojure-1.5.1.jar:/usr/local/lib/clojure-1.5.1/math.numeric-tower-0.0.2.jar
while [ "$1" != "${1%.jar}" ]; do # while param is a jar file
jars="$jars:$1"
shift
done
jars="$jars:."
exec rlwrap java -cp "$jars" clojure.main -e "(use 'clojure.math.numeric-tower)" "$#" -r
The middle part allows you to add jars on the command line, but in practice I don't find that useful, given that I use Leiningen for ongoing projects. Someone else might find that part of the script useful, though. rlwrap is a utility that gives you command line history, though it's not as good as what Leiningen provides, for my purposes.
After defining variables, functions, etc., can you save what you have done on the REPL too an text .clj file?
most people work with the repl through an editor such ad Eclipse/Emacs/vim and that editor has the ability to save the repl, though without some diligence on the developers part this will likely be an incomplete record of what happened. Some of the state of the repl may have come from loading files etc which will be in a different state.
So the short answer is typically not.
In Linux (mine = Ubuntu 16.04.2 LTS) if you are using lein then check for .lein (hidden directory) and look for repl-history. You should find the commands that you have typed or pasted into the REPL. This can be a source for later edit - I use geany...
I am answering the parenthetical part of your question. For me, the Clojure REPL is very useful for testing functions and proving out concepts that take no more than a few lines. I will often put hooks in a module that is not the main, just so I can load a file and run it through a couple of functions. I can also do this from main using the same mindset; that is write a debug function.
I found the Eclipse plugin to be quite useful, but I do not use it much these days, mostly Vim and running the module with one or more special functions and running the main. I don't know of any way to save REPL state.