Java EE web apps with Clojure (Maven and Leiningen are there, too!)

Sorry for party rocking! That’s really a crazy song, isn’t it? I do hope, the demo won’t be far from it :)

How could I never come up with the idea?! I’m just a day before I again showcase Clojure for Warszawa Java User Group (WJUG) and since there’ll be lots of people with Java EE background I came up with it – show how to use Clojure in Java EE applications. Well, they’re not any different from other Java applications, but guess it will surely help me introduce the language provided it brings a value. They will know it better, don’t they?

I believe it was during a walk with my youngest son (5 months and 2 days old) when he was sleeping and there’s nothing I could do, but to think about what I should be presenting during a WJUG meeting. I was wondering about an idea that would ultimately catch their attention for Clojure, and I’d need to show what they’re doing from another angle – have a Clojure script used in a JSP or a servlet. I believe it can do the trick and some will certainly appreciate the marriage.

These days, Apache Maven seems losing attention as the most comprehensive project management tool as the other alternative languages are catching up, and gradle, sbt or some kind of thereof leads the race. I don’t mean to learn or ask the audience to learn the other packaging tools, and since I’m the most comfortable with Maven (amongst the other tools I’ve just mentioned), I’ll stick with it.

As described on Maven’s Guide to Webapps, run the following command to generate a web application for our learning purposes:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp

It generates a web application called my-webapp in the current directory.

Clojure’s side of the webapp will be managed by Leiningen. Run lein new my-webapp-clj to generate a new Clojure project.

Edit src/my_webapp_clj/core.clj so it contains the following:

(ns my-webapp-clj.core
  (:gen-class
   :methods [[hello [String] String]]))

(defn -hello
  [this s]
  (str "Hello, " s))

Note the :gen-class and :methods directives in ns macro. They’re very important for the Java interop, and hence our demo. They basically say that during the project’s AOT compilation, a Java class called my_webapp_clj.core is to be generated (:gen-class) with the method hello(String) which returns a String object (:methods array).

Edit project.clj so it contains :aot :all in defproject as follows:

(defproject my-webapp-clj "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.3.0"]]
  :aot :all)

Note the line with :aot :all that will trigger AOT compilation for the entire project. No other changes are necessary.

Run lein install to AOT compile the namespace, package and install the project in a Maven repository.

jacek:~/sandbox/my-webapp-clj
$ lein install
Compiling my-webapp-clj.core
Compilation succeeded.
Created /Users/jacek/sandbox/my-webapp-clj/my-webapp-clj-1.0.0-SNAPSHOT.jar
Wrote pom.xml
[INFO] Installing /Users/jacek/sandbox/my-webapp-clj/my-webapp-clj-1.0.0-SNAPSHOT.jar to
/Users/jacek/.m2/repository/my-webapp-clj/my-webapp-clj/1.0.0-SNAPSHOT/my-webapp-clj-1.0.0-SNAPSHOT.jar

Back to the my-webapp project.

In pom.xml add the following dependency:

<dependency>
  <groupId>my-webapp-clj</groupId>
  <artifactId>my-webapp-clj</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</dependency>

It says that the my-webapp project depends on our Clojure project’s artifact.

Edit src/main/webapp/index.jsp so it looks as follows:

<html>
<body>
<h2>Hello World!</h2>
</body>
<p><%= new my_webapp_clj.core().hello("Jacek") %></p>
</html>

You may have noticed the scriptlet with new my_webapp_clj.core().hello("Jacek"). Although it’s not recommended to use scriptlets in JSP, it’s fine for the example. You’re strongly advised to create a servlet and call the my_webapp_clj.core class off it.

Run mvn package to package the webapp.

[INFO] Building war: /Users/jacek/sandbox/my-webapp/target/my-webapp.war

The webapp’s ready for deployment. Copy it to webapps directory of your Tomcat, and fire it up.

Open up http://localhost:8080/my-webapp/ and enjoy the Clojure and Java EE combo.

I can’t wait till I show it during tomorrow’s WJUG meeting. Nobody’s gonna apologize for some fun!

Be Sociable, Share!
This entry was posted in Java EE, Languages.

4 Responses to Java EE web apps with Clojure (Maven and Leiningen are there, too!)

  1. Jan Palencar says:

    Thank you for shraing, Jacek.

  2. Clojure can be also used to explore API of runnings web apps.
    For example I’ve used it as follows to explore Jira’s API:
    1. Install the Clojure Scripting Engine (http://code.google.com/p/clojure-jsr223/), Clojure and Swank on the server.
    2. Start Swank: (swank.swank/start-server :host “localhost” :port 4005)
    3. Create SSH tunnel to the server: ssh -L 4000:localhost:4005 web-app-server.com
    4. Connect Slime to localhost:4000 and hava fun:
    (ns jira (:import (com.atlassian.jira ComponentManager)))
    (.getIssueObject (.getIssueManager (ComponentManager/getInstance)) “issue-1234”)

    It’s really useful if you have to learn to use some API, for which it’s hard to write unit tests.

  3. Daniel Janus says:

    Przemek: This is truly awesome!

  4. Hey Przemek, what a crazy setup! Love it.

    When I showed how to change running application during the latest meeting of Warszawa JUG, I seemed to have noticed fear and uncertainity – they’re Java devs, so I wasn’t surprised and even anticipated it :)

Leave a Reply

%d bloggers like this: