How can I define a clojure type that implements the servlet interface?
Posted
by Rob Lachlan
on Stack Overflow
See other posts from Stack Overflow
or by Rob Lachlan
Published on 2010-05-18T01:22:34Z
Indexed on
2010/05/18
1:30 UTC
Read the original article
Hit count: 722
I'm attempting to use deftype (from the bleeding-edge clojure 1.2 branch) to create a java class that implements the java Servlet interface. I would expect the code below to compile (even though it's not very useful).
(ns foo [:import [javax.servlet Servlet ServletRequest ServletResponse]])
(deftype servlet []
javax.servlet.Servlet
(service [this
#^javax.servlet.ServletRequest request
#^javax.servlet.ServletResponse response]
nil))
But it doesn't compile. The compiler produces the message:
Mismatched return type: service, expected: void, had: java.lang.Object
[Thrown class java.lang.IllegalArgumentException]
Which doesn't make sense to me, because I'm returning nil. So the fact that the return type of the method is void shouldn't be a problem. For instance, for the java.util.Set interface:
(deftype bar [#^Number n] java.util.Set (clear [this] nil))
compiles without issue.
So what am I doing wrong with the Servlet interface?
To be clear: I know that the typical case is to subclass one of the servlet abstract classes rather than implement this interface directly, but it should still be possible to do this.
Stack Trace:
The stack trace for the (deftype servlet... is:
Mismatched return type: service, expected: void, had: java.lang.Object
[Thrown class java.lang.IllegalArgumentException]
Restarts:
0: [ABORT] Return to SLIME's top level.
Backtrace:
0: clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:6461)
1: clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:6119)
2: clojure.lang.Compiler$NewInstanceExpr$DeftypeParser.parse(Compiler.java:6003)
3: clojure.lang.Compiler.analyzeSeq(Compiler.java:5289)
4: clojure.lang.Compiler.analyze(Compiler.java:5110)
5: clojure.lang.Compiler.analyze(Compiler.java:5071)
6: clojure.lang.Compiler.eval(Compiler.java:5347)
7: clojure.lang.Compiler.eval(Compiler.java:5334)
8: clojure.lang.Compiler.eval(Compiler.java:5311)
9: clojure.core$eval__4350.invoke(core.clj:2364)
10: swank.commands.basic$eval_region__673.invoke(basic.clj:40)
11: swank.commands.basic$eval_region__673.invoke(basic.clj:31)
12: swank.commands.basic$eval__686$listener_eval__687.invoke(basic.clj:54)
13: clojure.lang.Var.invoke(Var.java:365)
14: foo$eval__2285.invoke(NO_SOURCE_FILE)
15: clojure.lang.Compiler.eval(Compiler.java:5343)
16: clojure.lang.Compiler.eval(Compiler.java:5311)
17: clojure.core$eval__4350.invoke(core.clj:2364)
18: swank.core$eval_in_emacs_package__320.invoke(core.clj:59)
19: swank.core$eval_for_emacs__383.invoke(core.clj:128)
20: clojure.lang.Var.invoke(Var.java:373)
21: clojure.lang.AFn.applyToHelper(AFn.java:169)
22: clojure.lang.Var.applyTo(Var.java:482)
23: clojure.core$apply__3776.invoke(core.clj:535)
24: swank.core$eval_from_control__322.invoke(core.clj:66)
25: swank.core$eval_loop__324.invoke(core.clj:71)
26: swank.core$spawn_repl_thread__434$fn__464$fn__465.invoke(core.clj:183)
27: clojure.lang.AFn.applyToHelper(AFn.java:159)
28: clojure.lang.AFn.applyTo(AFn.java:151)
29: clojure.core$apply__3776.invoke(core.clj:535)
30: swank.core$spawn_repl_thread__434$fn__464.doInvoke(core.clj:180)
31: clojure.lang.RestFn.invoke(RestFn.java:398)
32: clojure.lang.AFn.run(AFn.java:24)
33: java.lang.Thread.run(Thread.java:637)
© Stack Overflow or respective owner