views:

492

answers:

7

I'm beginning to play with Clojure a bit and my Java experience is pretty limited. I'm coming from the dynamic world of Ruby and OO, so the functional side of things is very interesting!

Anyway, as I discover libraries and various tools for use (and the tutorial files for the Pragmatic Clojure Book), everything typically calls for placing files in the CLASSPATH in order for Clojure to see the library for use.

Is there such thing as good CLASSPATH practice? Would I ever want to only have a CLASSPATH with just the external libraries of files I need or can I go ahead toss any library or file I would ever need in a directory and simply define it as my CLASSPATH and only require what's needed?

If it helps, I'm an OSX and Emacs user (Using slime and swank-clojure).

+1  A: 

We are using Clojure and use a number of infrastructure tools, especially Eclipse (IDE) (http://en.wikipedia.org/wiki/Eclipse%5F%28software%29) and maven (http://en.wikipedia.org/wiki/Apache%5FMaven). maven manages libraries and jar dependencies so if you have a number of these and they are likely to grow start using maven.

In answer to your original question you can just put your jars in one directory and you can access them by name every time you run. But you will benefit from the tools...

If you are just exploring then Eclipse will probably manage your jar files fairly painlessly. You can add these to the project as required through the Build Path -> Configure Build Path option.

As your work progresses you will possibly wish to split it into Projects which Eclipse supports so you can add your (or other projects) to your Build Path.

If you use external Clojure libraries look to see if they have been packaged as maven projects (they will have a pom.xml file). The POM will give a list of dependencies. #

peter.murray.rust
Eclipse is out of the question unfortunately. Like I mentioned, Emacs is what I'm using for Clojure dev.
mwilliams
+2  A: 

Personally, I'm using a variant of a clojure-project elisp function by Phil Hagelberg, see source in this post to the Clojure group. It sets up the classpath appropriately for the project you'll be working on, then launches SLIME. (**EDIT:** You'll need to change the value which gets assigned to swank-clojure-jar-path to point to clojure.jar. I'm using (expand-file-name "~/.clojure/clojure.jar") as the default.)

To answer the question about having everything on the classpath all the time vs only throwing in what's needed: to the best of my knowledge, nothing will actually break if you take the first approach (I know I do that for experimental purposes), but apparently things might break with the first approach (see cjstehno's comment below) and in a proper project I find the second to be cleaner. At some point it'll be necessary to determine what libs are being used (and which versions of them), if only to tell leiningen (or maven) about it -- why not keep tabs on it as you go.

Michał Marczyk
Actually if you put everything on the classpath you can run into problems, especially classloader collisions or erroneous classloading. It's usually best to have only what you need on the classpath for your specific application.
cjstehno
Oh, I see. Apparently I lucked out so far, but I'll keep that in mind for the future. Thanks for the comment, will edit accordingly.
Michał Marczyk
Ohhh I like Phil's clojure-project implementation, I think I'll give that a run and report back in a bit. Thanks!
mwilliams
Hmmm I can go ahead and find a project but slime is stuck trying to poll for a connection and it's just hanging. I'll have to troubleshoot this but I like where it's going. Thanks!
mwilliams
Sure. :-) You'll need to change `swank-clojure-jar-path` to point to `clojure.jar` to make it work; forgot about that when posting. Will edit accordingly. I think with this fix in place the whole thing should work...
Michał Marczyk
+1  A: 

The usual CLASSPATH practice for Java is to put only the jar files needed for a project into this projects class path, which means to have potentially different class paths for diffent projects. This is usually managed by the IDE as part of it's project properties.

Since you are using Emacs and thus probably don't have or use something like projects it might be more convinient for you to set up and use a single global class path for all your clojure related stuff or maybe even simply put all the needed jar files into the java2se/jre/lib/ext directory of your java installation.

The two main problems that could arise from having unneded jar files in your class path are: 1. it has a minor negative impact on the start up time of the JVM and 2. it becomes more difficult to make sure that you are not having classes with different versions in the same class path (i.e. different classes with the same package and name in different jar files).

x4u
+1  A: 

Since Java SE 1.6 (or JDK 1.6) you can include class path entries by wildcard. If your class files live in .\bin, and your library jar files live in .\lib, then on Windows you could define your class path like this:

set CLASSPATH=bin;lib\*;

This will let you add jar files into the .\lib directory and they will automatically be added to the class path for new instances of the JRE.

See this link for details: Setting the class path

Prior to JDK 1.6 you had to add each jar file onto the ClassPath individually.

richj
+6  A: 

I recommend using leiningen and lein-swank to manage this. You can start a REPL in the directory and connect to it from Emacs.

dnolen
A: 

I just discovered this bit which I need to give a shot:

(setq swank-clojure-extra-classpaths (list "/class/path/1" "/class/path/2" "/class/path/3" "etc"))

mwilliams
A: 

clojure-contrib/launchers/bash/clj-env-dir has an interesting property that you can point it at a directory and it will basically include anything in there. In the past I've had a ~/classpath directory which I would dump any jars into and link any commonly used directories and it worked great. Very simple way to dump and use. Now I tend to use Maven clojure-maven-plugin and that works well also though can be a bit tedious when you just want to muck around with some ideas.

Timothy Pratley