Clojure in Eclipse, Part 2: Counterclockwise + Maven
This article explains how Eclipse, Counterclockwise and Maven come together to form a powerful Clojure development platform.
In Part 1: Maven, I explained how to develop Clojure applications with Eclipse and its build automation tool Maven. In particular:
- We applied Maven's concept of build lifecycle to Clojure development: compilation, testing, packaging
- We customised the Maven lifecycle to our needs with Maven plug-ins
- We added Clojure specific pseudo-phases to Maven' lifecycle, such as running a clojure script or starting an interactive REPL.
- We saw that Maven would have compiled, tested, and deployed any Java code in our project.
As far as structured and monolithic compiled development goes, Maven is indeed a powerful one stop shop. But it needs something extra to satisfy our needs as Clojure developers.
- Clojure coding gadgets, such as code highlighting, code completion, code outlining.
- A feature rich REPL, to which we could send any script or any code snippet within a file.
This is precisely what Counterclockwise, the Clojure plugin for Eclipse, adds to the picture.
Let us install Counterclockwise first, and then go back to where we left at the end of our Maven tutorial. We will then observe the new features that Counterclockwise provides, delve into its productivity features, and look at how it eventually combines with Maven into a single powerful workflow.
Installing Counterclockwise
Install Counterclockwise like any other Eclipse plugin, via Help > Install New Software... . Specify one of the following update sites:
- http://ccw.cgrand.net/updatesite/ for stable releases
- http://ccw.cgrand.net/updatesite-betas/ for development releases
At the time of writing, I am installing the 0.6 version (from the beta site).
Creating a new project
You can either create a new Maven project or create a new Clojure project and work from there. The two options are really equivalent, with an equal (small) amount of tidying up required. I prefer giving the bulkiest animal precedence, and to start with a Maven project.
So let me quickly review how to start with a Clojure project first. I will then restart where we left at the end of our Clojure and Maven tutorial, which began with a Maven project.
Mavenizing a Clojure project
to start with a Clojure project:
- Create a new project via File > New > Project..., then Clojure Project, and name your project.
- Right-click on the project in the Package Explorer and execute Configure > Convert to Maven Project. Give the project a GroupId, a version number, a name and a description (see definitions)
- Delete the two Clojure jars in the project
- Follow the steps in Part 1: Maven
to:
- Create source directories and source files
- Configure Maven
- Create Eclipse launchers, aka Run Configurations
You will have to create extra directories for Java codes if you need them.
Clojurizing a Maven project
To start with a Maven project:
- Follow the steps in Part1: Maven to:
- Create a new Maven project
- Create source directories and source files
- Configure Maven
- Create Eclipse launchers, aka Run Configurations
- Right-click on the project in the Package Explorer and execute Enable/disable clojure language support.
Counterclockwise's features
Counterclockwise's features are explained in its documentation. The first ones you get out of the box are:
- syntax colouring, and in particular the LISP parenthesis colouring
- the outline of your code in Eclipse's standard Outline window.
But most of Counterclockwise's features come to life once you start a REPL. For Counterclockwise is really built around the REPL; without one running, things such as code completion will not work. So it helps to see the REPL as the hub from which all Counterclockwise functions emanate from. A corollary of this is that you must ensure that your REPL environment is loaded with:
- the namespaces that you want code completion to look into (if you turn the REPL off, no code completion anymore)
- the namespaces that you want the Namespace Browser to display
- the namespaces that you want the REPL preloaded with before you type commands in it, obviously.
Let us look at this properly.
I am restarting where we left at the end of Part1: Maven. You can catch up by downloading part one's tutorial project straight from GitHub.
- *ns* to see in which namespace we are
- (in-ns 'mynamespace) to move into mynamespace
- (all-ns) to view the list of all loaded namespace
- (filter #(nil? (re-find #"clojure.*" %)) (map str (all-ns))) to view loaded namespaces except Clojure's.
Starting a REPL from a Clojure file
Open maven.clj (In src/main/clojure, package chaomancy), which contains the main code of our application. From here:
- Execute Run > Run As > Clojure Application (preload file)
- This starts a REPL, loaded with namespace chaomancy.maven and all its dependencies.
- With the Clojure commands provided earlier, observe what namespaces are loaded, and check that we are in namespace chaomancy.maven.
- type (-main), to execute the main function of the application
- type (exclaim) to execute the inner logic of the application
- notice that the REPL is not running on its own. It is attached to a Console window (which you can jump to via an icon at the top right of the REPL). We'll need to stop both the REPL and this Console at the end.
REPL activated features
Now we can use Counterclockwise's REPL activated features:
- The Namespace Browser allows
inspecting all the namespaces and symbols loaded in the REPL.
- Open it via Window > Show View > Other... and choose Clojure Views > Namespace Browser
- expand package chaomancy.maven, double click on exclaim: this brings you to its declaration in the code
- expand package clojure.core, hover over an identifier: its documentation pops up
- Code Completion is triggered by Ctrl-Space.
For example:
- Go to the definition of exclaim in maven.clj. Delete defn, retype def and press Ctrl-Space to see the proposed expansions.
- Go to defn with the Down Arrow or click on it to see it's documentation.
- Press Enter or double-click to choose it.
- Snippet Evaluation is triggered by Ctrl-Enter.
This is Counterclockwise's most useful productivity feature in my
opinion, so do use and abuse it. For example:
- In -main, select only the bit: (println (exclaim)).
- Press Ctrl-Enter, which only sends this bit of code to the REPL.
So you don't have to reload a whole file after making a change to it; you can just evaluate the symbols you changed.
Loading a file in the REPL
You can load a file in an existing REPL via the Clojure menu, instead of starting a new REPL. Let us move across namespaces in the REPL to illustrate how this works:
- type (in-ns 'user) to move to the user namespace. typing (exclaim) doesn't work because we are not in namespace chaomancy.maven. Typing (chaomancy.maven/exclaim) works.
- In maven.clj, change the string in exclaim to anything you want. Select the whole definition of exclaim and press Ctrl-Enter. This created a new exclaim function in namespace user. Spot it in the Namespace Browser. type (exclaim) to run it.
- chaomancy.maven/exclaim is still the old version. We don't need to go back into namespace chaomancy.maven to change it. Open the Clojure menu and execute Load File in REPL. Counterclockwise understands that the symbols in the file should be created in namespace chaomancy.maven. Type (chaomancy.maven/exclaim). This executes the new version.
- You are still in the user namespace. Execute Clojure > Switch REPL to File's Namespace to get back to chaomancy.maven.
- Change the code back to what it used to be (check the application's test if you don't remember), and apply the change in whichever way you prefer.
Do experiment with other commands in the Clojure menu at your own pace.
Shutting the REPL down
To close and stop the REPL:
- Close the REPL window.
- AND terminate (red square icon) the Console that the REPL process is attached to.
Note that you can start several REPL side by side; they will each have their own Console process.
Counterclockwise productivity with Run Configurations
When you first start a REPL from a Clojure source file, Counterclockwise creates a permanent Run Configuration behind the scenes. You can customise Run Configurations to your own need. Let us look at this by example.
Scripts
Launching a script is done in exactly the same way as loading a namespace.
Now, a script usually performs a defined task, and you don't necessarily want a REPL to be started when you run one. You could load one in an existing REPL, but this may load namespaces and create symbols that will clutter your REPL. You might also want to make a script easily accesible via the GUI in order not to reopen the script's file everytime.
Let's show how to do this:
- Open script maven-run.clj (in the src/main/scripts folder) and run it in a new REPL with Run > Run As > Clojure Application (preload file). Notice that the output of the script was printed in the Console window, not in the REPL that was opened thereafter.
- Close the REPL and stop the Console for now.
- Execute Run > Run
Configurations... and go to the Clojure configuration called clj-maven-tutorial REPL [maven-run.clj].
- Tick Run with REPL off at the bottom of the Run Configuration page.
- We could run the configuration from here, but let's make it a favourite because it is our application's launcher. In the Common tab, tick Displays in Favorites Menu > Run.
- press Apply and Close.
- Expand the Run As dropdown (white arrow on green disk) in Eclipse's toolbar, and launch the Run Configuration. The script just runs in the Console, which stops after execution.
This will also work if you already have a REPL running, so it a great to run stuff without cluttering your development environment.
What we did here is a direct alternative to using the clojure:run goal in Maven.
Project REPL
Counterclockwise allows you to start a generic project REPL via the Package Explorer, and to initialise it as you want; this is precisely the purpose of the maven-repl.clj script.
- In the Package Explorer, right-click on the project's name and then Run As > Clojure Application. Only the Clojure namespaces are loaded. Close the REPL and stop the Console.
- Execute Run > Run Configurations... and go to the Clojure configuration called clj-maven-tutorial REPL. Click Choose in the Evaluate Clojure source file(s) box, and add script maven-repl.clj (in src/main/scripts). You could add a series of files here. Press Apply and Close.
You can now start this generic project REPL via the Package Explorer (you could add it to favorites too).
This is a direct alternative to using the clojure:repl goal in Maven. Counterclockwise is a much nicer REPL environment, although it won't launch lifecycle phases before starting the REPL as Maven did.
Configuration Wrap-up
The entire configuration path I recommend is the following:
- Create a new Maven Project
- Configure it as we did in Part1: Maven. Follow all steps, including the creation of run configurations for clojure:run and clojure:repl. Even if Counterclockwise does better, they may still be useful for diagnosis.
- Turn Clojure support on. Right-click on the project and execute Enable/disable clojure language support
- setup you main script (same as Maven) in Counterclockwise: run it and then edit its Run Configuration to make it REPL-less and a favorite.
- setup your general REPL script (same as Maven) in Counterclockwise: run it and then edit its Run Configuration to make it a favorite.
- Optional: setup the Package Explorer: run the project's REPL via the Package Explorer once, and then edit its Run Configuration to start the REPL script or the main run script.
Then:
- Start a REPL from the .clj file you want to code in. This activates Counterclockwise's REPL activated functions: Code completion, namespace browser, snippet evaluation.
- Start one-shot scripts via Run Configurations, some registered as favorites, without leaving your development REPL.
- If needed, start the generic project REPL in parallel to help you test or diagnose the application.
From there, you can run/load .clj files from 5 IDE locations:
- Run > Run As > Clojure Application (preload file): loads the file in the editor in a new REPL
- Clojure > Load File in REPL: loads the file in the editor in an existing REPL
- Run > Run Configurations...: runs/loads pre-registered files
- Run As dropdown button in the toolbar: runs/loads files pre-registered as favourites
- Right-click on the project in the Package Explorer and execute Run As > Clojure Application: runs/loads the pre-registered file(s)
Maven + Counterclockwise
We can finally conclude on what to do with Counterclokwise an what to do with Maven:
- Counterclockwise: Interactive REPL based development, with one or several REPL, and scripts. For this, Counterclockwise is infinitely more comfortable and flexible than Maven.
- Maven: All Clojure/Java lifecycle tasks i.e. compilation, testing, packaging and deployment; and dependencies management. The lifecycle will be customised with Maven plugins. Maven's REPL and script launcher can be used for diagnosis and troubleshooting.
In a more visual fashion:
Counterclockwise | Maven | |
---|---|---|
Phases | Interactive Clojure coding:
|
Bilingual life-cycle phases:
|
Troubleshooting | Interactive:
|
Life-cycle bound:
|
*,** click on the project in the Package Explorer and then: * built-in: under Run > Run As ** custom: under Run > Run As > Maven build |
||
What Next?
There is little you cannot do with Eclipse, Counterclockwise and Maven. So what else?
Counterclockwise itself is in active development, and the stable release of version 0.6 should come out any day now. The best places to follow the action are:
Now, a very expected feature is the integration of Leiningen in Eclipse/Counterclockwise, which you can read about in this informal Leiningen spec by Laurent Petit. In the meanwhile, this Poor man's integrating of Leiningen into Counterclockwise explains how to call Leiningen functions from Eclipse.
Reasons to use Leiningen instead of Maven can range from personal preferences to constraints. In a recent post, I explained how I decided to give a shot at Heroku to host Clojure applications, and Heroku requires projects to be compatible with... Leiningen. So something tells me I will write about Leiningen soon.
Another build tool for Clojure is the famous Leiningen. It is written in Clojure and for Clojure, and many prefer it to Maven. At the time of writing, it is not as tightly integrated in Eclipse as Maven, although this should soon change. Which of Leiningen and Maven is best to use very much depends on your own individual circumstances, background and taste.
But in a nutshell, you should like Maven if you like a tool that is: