atom feed1 message in com.googlegroups.clojureHello Clojure Servlet
FromSent OnAttachments
Craig McDanielAug 26, 2008 11:45 am 
Subject:Hello Clojure Servlet
From:Craig McDaniel (crai@gmail.com)
Date:Aug 26, 2008 11:45:53 am
List:com.googlegroups.clojure

Here is a simple "hello world" servlet project that runs under Tomcat. It may be useful to others. Note: This code works with the 20080612 Clojure release, but doesn't seem to find the doGet method when using the current SVN release.

*** Instructions ***

1. Edit build.properties in user home to specify Tomcat parameters catalina.home, manager.username, and manager.password.

2. Edit build.properties in project home to specify where clojure.jar and genclass.clj reside.

3. ant install

4. Go to http://localhost:8080/hello-clojure/hello

*** File List ***

./src/mypkg/HelloServlet.clj ./build.properties ./build.xml ./gen-classes.clj ./web/WEB-INF/web.xml

*** gen-classes.clj ***

(def genclass-file (first *command-line-args*)) (def build-dir (second *command-line-args*)) (load-file genclass-file) (clojure/gen-and-save-class build-dir 'mypkg.HelloServlet :extends javax.servlet.http.HttpServlet)

*** HelloServlet.clj ***

(clojure/in-ns 'mypkg.HelloServlet) (clojure/refer 'clojure)

(import '(java.io PrintWriter))

(defn doGet [this request response] (.setContentType response "text/html") (let [out (PrintWriter. (.getWriter response))] (doto out (println "<html>") (println "<head>") (println "<title>Hello World!</title>") (println "</head>") (println "<body>") (println "<h1>Hello World...from Clojure!</h1>") (println (str "17 + 3 = " (+ 17 3))) (println "</body>") (println "</html>"))))

*** build.properties ***

clojure.jar=${user.home}/clojure/clojure.jar genclass.clj=${user.home}/clojure/src/genclass.clj

*** web.xml ***

<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

<display-name>Hello, World Clojure Application</display-name> <description> This is a simple web application with a source code organization based on the recommendations of the Application Developer's Guide. </description>

<servlet> <servlet-name>HelloClojure</servlet-name> <servlet-class>mypkg.HelloServlet</servlet-class> </servlet>

<servlet-mapping> <servlet-name>HelloClojure</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>

</web-app>

*** build.xml ***

<project name="servlet-test" default="clojure.gen" basedir=".">

<!-- include the following in your build.properties file: * clojure.jar - full path of clojure.jar * genclass.clj - full path of genclass.clj --> <property file="build.properties"/>

<!-- include the following in your ~/build.properties file: * catalina.home * manager.username * manager.password --> <property file="${user.home}/build.properties"/>

<property name="app.name" value="hello-clojure"/> <property name="app.path" value="/${app.name}"/> <property name="app.version" value="0.1-dev"/> <property name="build.home" value="${basedir}/build"/> <property name="dist.home" value="${basedir}/dist"/> <property name="docs.home" value="${basedir}/docs"/> <property name="manager.url" value="http://localhost:8080/manager"/

<property name="src.home" value="${basedir}/src"/> <property name="web.home" value="${basedir}/web"/>

<path id="compile.classpath"> <!-- the main clojure jar --> <pathelement location="${clojure.jar}"/> <!-- Include all elements that Tomcat exposes to applications --> <fileset dir="${catalina.home}/bin"> <include name="*.jar"/> </fileset> <pathelement location="${catalina.home}/lib"/> <fileset dir="${catalina.home}/lib"> <include name="*.jar"/> </fileset> </path>

<!-- custom ant tasks --> <taskdef resource="org/apache/catalina/ant/catalina.tasks" classpathref="compile.classpath"/>

<!-- The "prepare" target is used to create the "build" destination directory, and copy the static contents of your web application to it. If you need to copy static files from external dependencies, you can customize the contents of this task.

Normally, this task is executed indirectly when needed. --> <target name="prepare"> <tstamp/> <!-- Create build directories as needed --> <mkdir dir="${build.home}"/> <mkdir dir="${build.home}/WEB-INF"/> <mkdir dir="${build.home}/WEB-INF/classes/mypkg/test"/> <!-- Copy static content of this web application --> <copy todir="${build.home}"> <fileset dir="${web.home}"/> </copy> <!-- Copy external dependencies as required --> <mkdir dir="${build.home}/WEB-INF/lib"/> <copy todir="${build.home}/WEB-INF/lib" file="${clojure.jar}"/> </target>

<!-- The clojure.gen target generates class files from *.clj files --> <target name="clojure.gen" depends="prepare"> <!-- Generate java class from clj file --> <mkdir dir="${build.home}/WEB-INF/classes"/> <java classname="clojure.lang.Script" classpathref="compile.classpath"> <arg value="gen-classes.clj"/> <arg value="--"/> <arg value="${genclass.clj}"/> <arg value="${build.home}/WEB-INF/classes"/> </java> <!-- Copy application resources --> <copy todir="${build.home}/WEB-INF/classes"> <fileset dir="${src.home}" excludes="**/*.java"/> </copy> </target>

<!-- The "dist" target creates a binary distribution of your application in a directory structure ready to be archived in a tar.gz or zip file. --> <target name="dist" depends="clojure.gen" description="Create binary distribution"> <mkdir dir="${dist.home}"/> <!-- Create application JAR file --> <jar jarfile="${dist.home}/${app.name}-${app.version}.war" basedir="${build.home}"/> <!-- Copy additional files to ${dist.home} as necessary --> </target>

<!-- The "clean" target deletes any previous "build" and "dist" directory, so that you can be ensured the application can be built from scratch. --> <target name="clean" description="clean up" > <delete dir="${build.home}"/> <delete dir="${dist.home}"/> </target>

<!-- The "all" target is a shortcut for running the "clean" target followed by the "compile" target, to force a complete recompile. --> <target name="all" depends="clean,clojure.gen" description="Clean build and dist directories, then clojure.gen"/>

<!-- The "install" target tells the specified Tomcat 6 installation to dynamically install this web application and make it available for execution. It does *not* cause the existence of this web application to be remembered across Tomcat restarts; if you restart the server, you will need to re-install all this web application.

If you have already installed this application, and simply want Tomcat to recognize that you have updated Java classes (or the web.xml file), use the "reload" target instead.

NOTE: This target will only succeed if it is run from the same server that Tomcat is running on.

NOTE: This is the logical opposite of the "remove" target. --> <target name="install" depends="clojure.gen" description="Install application to servlet container"> <deploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}" localWar="file://${build.home}"/> </target>

<!-- The "list" target asks the specified Tomcat 6 installation to list the currently running web applications, either loaded at startup time or installed dynamically. It is useful to determine whether or not the application you are currently developing has been installed. --> <target name="list" description="List installed applications on servlet container"> <list url="${manager.url}" username="${manager.username}" password="${manager.password}"/> </target>

<!-- The "reload" signals the specified application Tomcat 6 to shut itself down and reload. This can be useful when the web application context is not reloadable and you have updated classes or property files in the /WEB-INF/classes directory or when you have added or updated jar files in the /WEB-INF/lib directory.

NOTE: The /WEB-INF/web.xml web application configuration file is not reread on a reload. If you have made changes to your web.xml file you must stop then start the web application. --> <target name="reload" depends="clojure.gen" description="Reload application on servlet container"> <reload url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}"/> </target>

<!-- The "remove" target tells the specified Tomcat 6 installation to dynamically remove this web application from service.

NOTE: This is the logical opposite of the "install" target. --> <target name="remove" description="Remove application on servlet container"> <undeploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}"/> </target>

</project>