Browse files

Added with concept background thanks to slyphon.

  • Loading branch information...
1 parent e9862ce commit e535fe817ce88bb42ebaa080acb8f8c8f7feb69b @technomancy technomancy committed Mar 13, 2010
Showing with 108 additions and 5 deletions.
  1. +77 −0
  2. +4 −0 NEWS
  3. +27 −5
@@ -0,0 +1,77 @@
+# Introduction to JVM Packaging Concepts
+For those of you new to the JVM who have never touched Maven in anger:
+don't panic. Leiningen is designed with you in mind. Leiningen is
+built on some Maven libraries; specifically the dependency resolution
+parts. These aspects of Maven are not nearly as complex as the build
+features that have given it its somewhat fearsome reputation. Think of
+it as the package manager of the JVM world, much like Rubygems, CPAN,
+etc. There is a central canonical repository, a Clojure-specific
+repository called Clojars, and projects often also make their jars
+available through project-specific public repositories. It allows you
+to define the dependencies of your project, which it then goes and
+retrieves, stores in a local repository ("~/.m2" on Unix by default),
+and copies into your project's "lib/" directory. This makes it so that
+you don't have to check your dependent jar files into your SCM or make
+developers hunt down dependency jars by hand.
+Leiningen describes packages using identifiers that look like:
+ org.clojure/swank-clojure "1.0"
+* "org.clojure" is called the 'group-id'
+* "swank-clojure" is called the 'artifact-id'
+* "1.0" is the version of the jar file you require
+Sometimes versions will end in "-SNAPSHOT". This means that it is not
+an official release but a development build. In general relying on
+snapshot dependencies is discouraged, but sometimes its necessary if
+you need bug fixes etc. that have not made their way into a release
+yet. Adding a snapshot dependency to your project will cause Leiningen
+to actively go seek out the latest version of the dependency every
+time you run "lein deps", (whereas normal release versions just use
+the local cache) so if you have a lot of snapshots it will slow things
+While it's customary to make group IDs match either artifact IDs or
+the Java package, it's not required. Let's take for an example the
+[JYaml jar]( Looking at their javadocs,
+the Java package name is "org.ho.yaml". If you try to add the
+following dependency in your project.clj file:
+ [org.ho.yaml/jyaml "1.3"]
+You'll get an error when you run "lein deps". One way to find the
+correct group id is to use a maven search web site like
+[Jarvana]( In the "project search" box, enter
+"jyaml", and you'll see results that indicate the correct group-id
+("org.jyaml") and artifact id ("jyaml").
+If the jar you're looking for is published in a project's own public
+repository instead of the central one, you can use the :repositories
+option in project.clj. For instance, if we wanted to use the jars from
+the HornetQ project:
+ (defproject com.motionbox.hornetq/dashboard "0.0.1-SNAPSHOT"
+ :description "a simple web interface to the hornetq jmx API"
+ ;; this repository will be referred to in log messages as "jboss-release"
+ :repositories {"jboss-release" ""}
+ :dependencies [[org.clojure/clojure "1.1.0"]
+ [org.clojure/clojure-contrib "1.0-SNAPSHOT"]
+ [commons-logging "1.1.1"]
+ [org.hornetq/hornetq-core "2.0.0.GA"]
+ [org.hornetq/hornetq-jms-client "2.0.0.GA"]
+ [org.hornetq/hornetq-transports "2.0.0.GA"]
+ [org.hornetq/hornetq-logging "2.0.0.GA"]
+ [org.jboss.netty/netty "3.1.0.GA"]
+ [org.jboss.javaee/jboss-jms-api "1.1.0.GA"]
+ [log4j "1.2.15" :exclusions [javax.mail/mail
+ javax.jms/jms
+ com.sun.jdmk/jmxtools
+ com.sun.jmx/jmxri]]
+ ]
+ :dev-dependencies [[swank-clojure "1.1.0"]]
+ :namespaces [com.motionbox.hornetq])
+For an in-depth walkthrough see the Full Disclojure screencast:
@@ -1,5 +1,9 @@
Leiningen NEWS -- history of user-visible changes
+= 1.2.0 / ???
+* Added file for introductory concepts.
= 1.1.0 / 2010-02-16
* Added "lein upgrade" task
@@ -26,13 +26,21 @@ rather than copying and pasting among each of your projects.
## Installation
+Leiningen bootstraps itself using the 'lein' shell script you
+download, there is no separate 'install script'. It installs its
+dependencies in $HOME/.m2/repository.
1. [Download the script](
2. Place it on your path and chmod it to be executable.
3. Run: <tt>lein self-install</tt>
This only works with stable versions of Leiningen; for development
versions see "Hacking" below.
+On Windows you can download
+instead, though support on that platform is still experimental.
## Usage
$ lein deps # install dependencies in lib/
@@ -59,7 +67,7 @@ versions see "Hacking" below.
## Configuration
-Place a project.clj file in the project root that looks something like this:
+Place a project.clj file in the project root that looks something like this:
(defproject leiningen "0.5.0-SNAPSHOT"
:description "A build tool designed not to set your hair on fire."
@@ -104,6 +112,11 @@ Other keys accepted:
functions and are able to write it with a more pleasing syntax, it's
not bad.
+**Q:** What's a group ID? How do snapshots work?
+**A:** See the
+ [intro](
+ for background on JVM dependency concepts.
**Q:** What if my project depends on jars that aren't in any repository?
**A:** Open-source jars can be uploaded to Clojars (see "Publishing"
below), though be sure to use the groupId of "org.clojars.$USERNAME"
@@ -112,6 +125,19 @@ Other keys accepted:
Alternatively you can install into your local repository in ~/.m2
with Maven for Java libs or "lein install" for Clojure libs.
+**Q:** What does java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V mean?
+**A:** It means you have some code that was AOT (ahead-of-time)
+ compiled with a different version of Clojure than the one you're
+ currently using. If it persists after running "lein clean" then it
+ is a problem with your dependencies. If you depend on contrib, make
+ sure the contrib version matches the Clojure version. Also note for
+ your own project that AOT compilation in Clojure is much less
+ important than it is in other languages. There are a few
+ language-level features that must be AOT-compiled to work, generally
+ for Java interop. If you are not using any of these features, you
+ should not AOT-compile your project if other projects may depend
+ upon it.
**Q:** It looks like the classpath isn't honoring project.clj.
**A:** Leiningen runs many things in a subclassloader so it can
control the classpath and other things. Because of this, the
@@ -137,10 +163,6 @@ Other keys accepted:
and the Plexus Classworlds container was an ornery beast causing
much frustration. The maven-ant-tasks API is much more manageable.
-**Q:** What about Windows?
-**A:** Try the bin/lein.bat script. Note that Windows support is still
- experimental; not all features (notably self-install) are implemented.
## Publishing
If your project is a library and you would like others to be able to

0 comments on commit e535fe8

Please sign in to comment.