Where should the file user.clj go? - clojure

I am trying to setup proto-repl atom-editor package and apparently it needs a file user.clj to exist somewhere - which I guess is some leiningen's init file.
Where should I create this file?

Clojure will load the file user.clj from your class path if it is found. In a default leinengen project src/ will be on the class path, so if you create src/user.clj the contents of that file will be loaded in the context of the user namespace.
user is the default namespace for the clojure repl, but some leiningen projects override this. In order to access definitions in user.clj you will need to either pull user into scope (using require or use) or make sure that user is your starting namespace.

See the Proto REPL demo project https://github.com/jasongilman/proto-repl-demo/blob/master/dev/user.clj for an example of how to setup user.clj You should also add a dependency on clojure.tools.namespace in the project.clj https://github.com/jasongilman/proto-repl-demo/blob/master/project.clj
I just pushed some changes to Proto REPL last night to improve this area but you'll still benefit from having one setup.

According to the proto-repl page, it might use some functions from user namespace when reloading code in REPL (reset function) but it shouldn't be required.
You might want to take a look at the proto-repl demo project to see the more advanced setup.

Related

External jars with Dropwizard

I am trying to write a Dropwizard application and its doc tells me that I need to ship everything as an uber jar.
However, in my application I need to support multiple databases and this requires multiple database JDBC driver jars in my classpath, all of which are not expected to be shipped together with my application. Users are expected to place the corresponding JDBC jar like mysql-connector-java-5.1.39.jar in a particular folder by their own.
After reading Dropwizard's documentation I am not sure if this kind of usage is supported. Does anyone have experience making it to work this way?
Since java 6, you can wildcard classpaths.
Using the application plugin, the generated bin folder will have a start script that contains the classpath. What we want to do, is to instead of listing every possible jar in the bin folder, we simply include all of them.
Note: You can also do the same thing with different folders if you want the classpath in a different location.
This can be achieved (in a workaround manner since there are problems with this plugin in my version) in the easiest way as follows. In build.gradle you do:
startScripts {
doLast {
def windowsScriptFile = file getWindowsScript()
def unixScriptFile = file getUnixScript()
windowsScriptFile.text = windowsScriptFile.text.replaceAll('CLASSPATH=.*', 'CLASSPATH=\\$APP_HOME/lib/*')
unixScriptFile.text = unixScriptFile.text.replaceAll('CLASSPATH=.*', 'CLASSPATH=\\$APP_HOME/lib/*')
}
}
This will wildcard your lib folder in the start scripts. When starting up, your classpath will simply be
lib/*
When you drop jars into that folder, they will automatically be picked up (on startup, not on runtime).
I hope this helps,
Artur

Problems while opening the REPL

Anytime I fire up a fresh REPL I always get the same message, namely
#<FileNotFoundException java.io.FileNotFoundException: Could not locate test_app/core_init.class or test_app/core.cljon classpath:>
The namespace I've been using is ns test-app.core
The REPL still continues to come up and I am able to execute code with it. I am just unsure if this will lead to future problems, such as trying to work with incanter or other libraries.
Does your project.clj contain the following line, per chance?
...
:main test-app.core
...
Leiningen will try to switch into that namespace before showing the REPL to you. If it cannot find it, you'll see the error you mentioned. Now, the reason it cannot find it is another topic to explore, so first make sure that this is how your directory structure looks like:
.
|-- project.clj
|-- src
|-- test_app
|-- core.clj
If it does, I guess it's time to post Leiningen and Java versions (and ideally your project.clj) to let SO try to tackle this miraculous REPL. :)
Edit: The solution to this problem would - if any of the above suggestions match your case - of course be to either remove the :main line from your project file or to adjust the directory structure.
There needs to be a core.clj file in the folder named test_app in your project structure.
Basically, the file name should apply the naming towards whatever you've declared in your ns form.
As the Clojure Documentation FAQ says,
In order to use a Java class or Clojure namespace in your program,
that class or namespace must be "on the classpath," that is, inside a
directory or JAR file listed in the classpath.

Can org-mode babel tangle produce leiningen directories?

We want to automate the production of a Leiningen project tree
entirely from an org-mode babel file. We want to do this so that we
can also create beautiful, typeset documentation via
org-latex-export-to-pdf. We want no less than full literate
programming in Clojure from org-mode.
The following command:
$ lein new ex1
produces a tree that looks like this:
ex1
ex1/.gitignore
ex1/doc
ex1/doc/intro.md
ex1/project.clj
ex1/README.md
ex1/resources
ex1/src
ex1/src/ex1
ex1/src/ex1/core.clj
ex1/test
ex1/test/ex1
ex1/test/ex1/core_test.clj
We want to do the identical thing just by running
org-babel-tangle, and no more, in our org-mode buffer in
emacs.
A difficulty arises: whereas tangle is happy to produce
files in existing subdirectories like src and test, it seems reluctant to produce the subdirectories if they don't exist. That means we must
create the directory structure by some other means -- unless we can
get tangle to do it for us, and that's the subject of this
StackOverflow question.
There are six files in the directory structure created by Leiningen. I can remove them all and re-create them from my org-file with BEGIN_SRC blocks such as the following
#+BEGIN_SRC clojure :tangle ./ex1/src/ex1/core.clj
(ns ex1.core)
(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!"))
#+END_SRC
Notice particularly the name of the subdirectory path
#+BEGIN_SRC clojure :tangle ./ex1/src/ex1/core.clj
All is well if our directory structure already exists. org-mode's tangle will
create or update all six files described above and create new files in any existing directory. We don't know how to
get tangle to produce the directories; it complains that there is no such
directory.
A copy of the desired .org file can be found here if you would like more details.
It is possible use the following header in the begin_src section,
:mkdirp yes
FYI There's now a lein project template for using org based projects:
https://github.com/thi-ng/thing-babel

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.)

Clojure emacs slime + swank directory question

I'm using emacs with clojure-swank and slime and trying to set my development environment. And I ran into a problem. When I start a repl I'm stuck in an unknown directory preventing me to load my namespace. Because the clojure repl can't find the right file.
Does anyone know how to change the current directory?
PS: I've just started using emacs and slime so I'm a noob.
If you want to change slime's notion of the current directory, press ,cd<CR> (<CR> = Enter) and type in the path.
However, this is not really the proper solution to the problem. The proper solution involves setting up the classpath so that you can (use 'your.namespace). To this end, I wonder if this very long answer I provided to a question about setting up the classpath properly might be helpful... :-)
Incidentally, I somewhat object to solutions involving add-classpath, as that is currently marked as deprecated and was never meant to be relied upon in the first place... Though on the other hand, it certainly may work perfectly well and it's worth knowing about just in case it might come in handy as a quick-and-dirty classpath injection gimmick.
Now if you want a real nice SLIME-based development environment, I'd like to point you to a very nice clojure-project elisp function by Phil Hagelberg which sets up all relevant variables and launches SLIME in the main directory of a project (to be supplied interactively). It's been posted to the Clojure group, in fact here's a link to the Mail Archive's copy of that message. Note there's one thing which needs correction in there -- swank-clojure-jar-path ought to be set to the full path to clojure.jar. Otherwise it's a fantastic tool.
Actually I mentioned that function in this response to a question about managing the classpath when using Clojure and Emacs. The other answers might be interesting as well.
And if you're only just beginning to use SLIME, do watch the SLIME video, linked to from SLIME's homepage which is now available under a link posted by Michiel in the comments. It's a very good introduction. :-)
Leiningen is a new Clojure build tool that worries about classpathing for you. You set up a simple project file in the project's root directory to specify the main class of your project, and it automagically discovers all the JARs in your lib directory and loads them for you.
I now just type "lein swank" at a command line and then M-x slime-connect in Emacs, and everything just works. (This could easily be automated with a little Elisp.)
More info in this blog post.
Short answer:
(load-file "full-path-to-definition")
Long answer:
Here's what my bootstrapping process looks like:
In ~/.clojure/user.clj (this file is auto-run when you boot slime/clojure):
(add-classpath "file://path/to/foo.jar") ; Include these jars in the classpath
(add-classpath "file://path/to/foo2.jar")
(load-file "file://workspace/bootstrap.clj")
In bootstrap.clj:
(compile 'my.package)
Package file(s) is at /workspace/my/package.clj
In package.clj:
(ns my.package)
(defn foo [] (+ 2 2))
The best approach I've found when using Emacs, SLIME and swank-clojure is to use the (Emacs Lisp) function swank-clojure-project. From its documentation:
(swank-clojure-project PATH)
Setup classpath for a clojure project and starts a new SLIME session.
Kills existing SLIME session, if any.
If you do a "M-x swank-clojure-project", it will interactively prompt you for your project directory; once you've selected it, all the jars in a lib subdirectory, as well as the src and classes folder will be added to your classpath. It will also honor a Maven/lein directory structure, in other words: it will usually just work.
If you change something, e.g. add a new jar file, simply do swank-clojure-project again.