JBoss.orgCommunity Documentation

Chapter 11. Interactive Development

11.1. Introduction

Immutant provides two methods for connecting to an application's runtime with a REPL: Swank (for emacs) and nREPL (for any nREPL client).

Each REPL service runs on a unique port, allowing you to have REPLs into multiple applications within the same Immutant, or mutltiple REPLs within the same application.

REPL services can be started at application deploy time, or dynamically from application code. REPLs started dynamically can be also be shutdown dynamically. REPLs started at deploy time and any dynamically started REPLs that are not shut down by the application will be shut down when the application is undeployed.

11.1.1. Binding To An Interface

AS7 is setup to use multiple network interfaces, and allows you to specify different interfaces for your server: public, management, and unsecure. By default, these interfaces are all the same - 127.0.0.1. But you can specify different addresses for each named interface, aiding in the security setup of your management ports.

By default, the repl services started by Immutant bind to the management interface.

11.2. Swank

Swank is the server protocol for SLIME (The Superior Lisp Interactive Mode for Emacs), and Clojure Swank & SLIME support are provided by swank-clojure & clojure-mode, respectively.

11.2.1. Starting Swank

You can start a Swank service using one (or both) of two methods: specifying a :swank-port option in your configuration, or by calling immutant.repl/start-swank from application code. No matter which method you use, there can only be one Swank service running for an application.

11.2.1.1. Starting Swank Via :swank-port

To have Immutant start a Swank service on your behalf, you can specify an open port for it to bind to using the :swank-port configuration option. When using this option, Immutant will automatically bind to the management interface.

11.2.1.2. Starting Swank Programatically

You can also start a Swank service from your own code, which is useful if you need to start it in response to a runtime event or bind to an interface other than the management interface. To do so, simply call immutant.repl/start-swank:

;; bind to the given port on the management interface
(clojure.repl/start-swank 4242)

;; bind to the given port and interface
(clojure.repl/start-swank 4242 "127.0.0.1")

11.2.2. Connecting to Swank

Installing SLIME under emacs to work with Clojure can be a painful and confusing process if done manually. The easiest way to do it is to follow the clojure-jack-in instructions from swank-clojure, and "jack in" to any Leiningen project. This will trigger clojure-mode to download and install a version of SLIME that is compatible with swank-clojure. Once you have jacked in at least once, you can then connect to the Swank service within your Immutant application via the slime-connect emacs function (M-x slime-connect RET).

11.2.3. Shutting Down Swank

Immutant will automatically shutdown the Swank service for you when your application is undeployed, but if you need to do so before undeploy you can do so using the immutant.repl/stop-swank function:

;; no arg needed since only one Swank server can exist for the application
(clojure.repl/stop-swank)

11.3. nREPL

nREPL is a client/server protocol that provides a Clojure across a network. It is relatively new, but has several clients built around it.

11.3.1. Starting nREPL

You can start a nREPL service using one (or both) of two methods: specifying an :nrepl-port option in your configuration, or by calling immutant.repl/start-nrepl from application code.

11.3.1.1. Starting nREPL Via :swank-port

To have Immutant start a nREPL service on your behalf, you can specify an open port for it to bind to using the :nrepl-port configuration option. When using this option, Immutant will automatically bind to the management interface.

11.3.1.2. Starting nREPL Programatically

You can also start a nREPL service from your own code, which is useful if you need to start it in response to a runtime event or bind to an interface other than the management interface. To do so, simply call immutant.repl/start-nrepl. nREPL allows you to have multiple services in the same runtime, so you need to save the return value of start-nrepl if you want to shut down the nREPL service yourself:

;; bind to the given port on the management interface, and
;; save the service handle for later
(def nrepl (clojure.repl/start-nrepl 4242))

;; bind to the given port and interface
(clojure.repl/start-swank 4242 "127.0.0.1")

11.3.2. Connecting to nREPL

Installing SLIME under emacs to work with Clojure can be a painful and confusing process if done manually. The easiest way to do it is to follow the clojure-jack-in instructions from swank-clojure, and "jack in" to any Leiningen project. This will trigger clojure-mode to download and install a version of SLIME that is compatible with swank-clojure. Once you have jacked in at least once, you can then connect to the nREPL service within your Immutant application via the slime-connect emacs function (M-x slime-connect RET).

11.3.2.1. Connecting via reply

reply is an enhanced REPL for Clojure, and supports connecting to an nREPL service. Currently, the simplest way to install reply is to clone the git repository and follow the intructions in its README.

Once you have reply installed, you can connect to your remote nREPL:

# connect to an nREPL bound to port 4242 on localhost
$ reply --skip-default-init --attach 4242 

# connect to an nREPL bound to port 4242 on 10.0.0.10
$ reply --skip-default-init --attach 10.0.0.10:4242 

Note that we are passing the --skip-default-init option above. reply attempts to load some libraries that won't exist in the application's runtime within Immutant, and also creates handy quit & exit functions that map to System/exit, which will shutdown the entire application server. Passing the --skip-default-init option prevents reply from attempting to load those missing libraries and prevents the definition of quit and exit.

11.3.2.2. Connecting via vimclojure

Coming soon.

11.3.2.3. Connecting via Counterclockwise

Coming soon.

11.3.3. Shutting Down nREPL

Immutant will automatically shutdown any nREPL services for you when your application is undeployed, but if you need to do so before undeploy you can do so using the immutant.repl/stop-nrepl function. You'll need to pass it the service handle returned by the start-nrepl call:

(clojure.repl/stop-nrepl nrepl)

Since you need the service handle to stop an nREPL service, you can only manually stop nREPL's you start yourself. If you start an nREPL service via the :nrepl-port configuration option, your only recourse is to allow Immutant to shut it down for you on undeploy.

Immutant 0.1.0