Thursday, April 11, 2013

Running and debugging Clojure code with Intellij IDEA

In the following blog post, I will show how to install La Clojure plugin, import project from leiningen to IntelliJ IDEA, how to interact with REPL and finally how to use IDEA's debugger to debug Clojure code run from REPL. 
These features make Clojure development with IDEA a real pleasure.

Installation of La Clojure plugin

To use Clojure with IntelliJ IDEA, we have to add La Clojure plugin. To do that, we open File / Settings / Plugins from a menu, than click on Browse repositories... button at the bottom of the Settings window (highlighted in red).


Then, we select La Clojure from plugins list (we can use filter in the right top corner of the window), right click on the item and select Download and Install command:


Upon leaving the Settings window, IDEA will ask if we want to restart it - the plugin will not work unless we do.

Importing leiningen project

With the La Clojure plugin ready and active, we can import a leiningen project into IntelliJ IDEA. All we have to do is to generate appropriate Maven pom.xml file:

lein pom

Then, we can import the maven module using IntelliJ IDEA.

Step 1: select Import Project from welcome screen:


Step 2: point IDEA to pom.xml (not project.clj) file:


After steps above, you can follow standard IntelliJ IDEA Maven project import procedure: confirm Maven project options, select IDE, set project name and IDEA files location for a project.

One thing that has to be done manually is adding Clojure Facet to project modules. To do that, we simply select File / Project structure from a menu, then navigate to our module in Modules tab, click on a + sign and finally select Clojure:


Starting the REPL


With Maven project loaded successfully, IDEA will fetch dependencies which aren't already in Maven local repository. With these libraries fetched, we can start Clojure REPL for our project by selecting Tools / Start Clojure Console from a menu. 

We can also use the keyboard shortcut - Ctrl-Shift-D by default in the newest La Clojure version.

The REPL will set a classpath for all of our libraries and sources referenced in a current module:



Interacting with REPL

To load a current Clojure file to REPL by a load-file function, all we have to do is to select Tools / Clojure REPL / Load file to REPL or use a keyboard shortcut - Ctrl-Shift-L by default.


We can also use Tools / Clojure REPL menu to:
  • Run selected text in REPL 
  • Execute last S-Expression in REPL
  • Run top S-Expression in REPL

Debugging with REPL

With IntelliJ IDEA we can connect a remote debugger to a REPL, allowing us to debug our Clojure code.

Step 1: we have to create a Remote Debugger profile using Run / Edit Configurations... from a menu.
To add a Remote Debugger, we have to click on the plus '+' sign and select 'Remote' configuration type:


We can adjust the settings or leave them as default. Most importantly, we have to copy command line arguments for running remote JVM, for example:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

The default value for port is 5005, but it can be adjusted in case there is another process already listening on that port.

It is also convienient to name this Remote Debugging session as 'Clojure REPL Debugger' for example.

Step 2: apply command line arguments to REPL settings for Clojure facet in our module (File / Project Structure / Modules / [our module] / Clojure / JVM arguments):



Step 3: Start a REPL with Tools / Start Clojure Console or a keyboard shortcut - Ctrl-Shift-D by default:


If the REPL is already running, it needs to be stopped and started again.

Step 4: Start Remote Debugger configuration created in step 1 with Run / Debug 'Clojure REPL Debugger' or a keyboard shortcut - Shift-F9 by default.


The name of Remote Debugger configuration is dependent on the configuration created in step 1. For the sake of example, I am using 'Clojure REPL Debugger'.

And finally, with the Remote Debugger ready and connected to REPL, we can debug our Clojure code:





10 comments :

  1. Does this work with the community version of INTELLIJ, or is it necessary to have the commercial vesion?

    ReplyDelete
  2. The tutorial was based on IntelliJ IDEA Community Edition and La Clojure plugin works with it just fine.
    So an Enterprise/commercial version is not necessary at all, but should work as well.

    ReplyDelete
  3. Clearest explanation I have seen so far to get Clojure running in IntelliJ. Very many thanks!! :)

    ReplyDelete
  4. "So an Enterprise/commercial version is not necessary at all, but should work as well." ... yes, it works! (at least in the academic one).

    Thank you for this post, helped a lot.

    ReplyDelete
  5. Thanks for this tutorial, it encouraged me to try Intellij for the first time.

    I followed along, and got all the way to the last step of "Run / Debug 'Clojure REPL Debugger'". Intellij attempted to compile the project, but gave a strange error message "Clojure Compiler: java.io.IOException: No such file or directory, compiling: /path/to/core.clj".

    /path/to/core.clj definitely exists, though, because "Tools -> Clojure REPL -> Load file to REPL" works as expected.

    Are there any further steps I should take to get Intellij compiling the code without complaint?

    ReplyDelete
  6. You actually don't need to compile the project with Intellij IDEA to run it - it is significantly faster to just load the files with REPL.

    I think that it is also a default for remote debugging session in IDEA to not build the project - just attach to the remote socket.

    Hope that helps.

    ReplyDelete
  7. Note that there is also a Leiningen plugin for Intellij IDEA that allows you to import project.clj so you don't need to run "lein pom". (Also there exists a plugin for Leiningen called lein-idea which can generate IDEA project file, but the Leiningen plugin for IDEA will keep your IDEA project synced with project.clj, so I prefer that over lein-idea or lein pom methods.)

    ReplyDelete
  8. That's right - there's a number of ways to import Clojure project into IntelliJ.

    ReplyDelete