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!