Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NPE installing a Clojure WAR in Tomcat, restart fixes

I'm attempting to deploy a WAR file written in Clojure to Tomcat 6 on Debian Lenny.

I'm getting a NullPointerException when I copy it into the webapps dir (both for the first type and when overwriting an existing war). Strangely, restarting Tomcat fixes the issue and the servlet runs fine. I packaged the WAR with leiningen-war (also tried lein-ring). The servlet works fine when using Jetty.

Here's the relevant log entry from Tomcat:

Jan 12, 2011 7:18:06 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Allocate exception for servlet foobar
  java.lang.NullPointerException
    at clojure.lang.Var.invoke(Var.java:373)
    at clojure.lang.AFn.applyToHelper(AFn.java:169)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.lang.Compiler.macroexpand1(Compiler.java:5286)
    at clojure.lang.Compiler.macroexpand(Compiler.java:5341)
    at clojure.lang.Compiler.eval(Compiler.java:5409)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.RT.loadResourceScript(RT.java:340)
    at clojure.lang.RT.loadResourceScript(RT.java:331)
    at clojure.lang.RT.load(RT.java:409)
    at clojure.lang.RT.load(RT.java:381)
    at clojure.core$load$fn__4511.invoke(core.clj:4905)
    at clojure.core$load.doInvoke(core.clj:4904)
    at clojure.lang.RestFn.invoke(RestFn.java:409)
    at clojure.lang.Var.invoke(Var.java:365)
    at foobar.servlet.<clinit>(Unknown Source)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

Here's the source, simplified to the bare minimum:

(ns foobar.servlet
  (:use [ring.util.servlet :only [defservice]])
  (:gen-class :extends javax.servlet.http.HttpServlet))

(defn handler
  [req]
  {:status 200
   :headers {"Content-type" "text/html"}
   :body "hi"})

(defservice handler)

Relevant lein dependencies:

[org.clojure/clojure "1.2.0"]
[ring/ring-core "0.3.4"]
[ring/ring-servlet "0.3.4"]

I made sure there are no duplicate JARs in the WAR and Tomcat's lib dir.

I'm at a loss. Anyone know what's wrong or have troubleshooting tips? Having to restart Tomcat on every deploy is a pain in the butt.

like image 828
Justin Kramer Avatar asked Jan 12 '11 20:01

Justin Kramer


2 Answers

This may or may not have anything to do with your problem, but I've noticed that sometimes Tomcat prematurely deploys a WAR file (especially a large one) that has not been written completely to the webapps directory. This is not Tomcat's fault; it can't know when the file is complete.

I now always copy a WAR file into a running Tomcat by copying it to, say, webapp.war.disabled and then renaming it: mv webapp.war.disabled webapp.war.

like image 177
Christoph Seibert Avatar answered Sep 18 '22 14:09

Christoph Seibert


I did almost the same thing but used tomcat 5.5.34 and it worked.

I added this dependency to project.clj:

[ring "1.0.0-RC1"]

I added this dev-dependency to project.clj:

:dev-dependencies [[lein-ring "0.4.6"]]

I added the ring configuration to project.clj and made sure my handler function was named 'handler':

:ring {:handler simple.webapp.core/handler}

I ran lein ring uberwar then I renamed the resulting war file so that it didn't contain the "-1.0.0-SNAPSHOT.standalone" in the name before copying the war file to tomcat's webapps/ directory.

Forgot to mention that I was using clojure 1.3.0.

like image 31
FielC Avatar answered Sep 20 '22 14:09

FielC