0

I am trying to implement the following in Clojure:

Handler:

// http/handlers/EchoHandler.java
package http.handlers;

import org.rapidoid.http.Req;
import org.rapidoid.u.U;

import java.util.Map;

public class EchoHandler {

    public static Map<String, String> handleEcho(Req req) {
        return U.map(req.headers());
    }
}

Server:

import http.handlers.EchoHandler;
import org.rapidoid.config.Conf;
import org.rapidoid.setup.On;

public class HttpServer {


    public static void start() {
        Conf.HTTP.set("serverName", Defaults.SERVER_NAME);
        Conf.HTTP.set("maxPipeline", Defaults.MAX_PIPELINE);
        On.get("/echo").managed(false).json(EchoHandler::handleEcho);
   }
}

Now trying to do the same in Clojure:

(ns harrow.http
  (:require
    ; harrow
    ; external
    [clojure.tools.logging  :as log       ] )
  (:import
    [org.rapidoid.config    Conf              ]
    [org.rapidoid.setup     On OnRoute        ]
    [org.rapidoid.http.impl RouteOptions      ]
    [org.rapidoid.http      Req               ]
    [org.rapidoid.u         U                 ]
    [java.util              Map LinkedHashMap ] ) )

(gen-class
  :name harrow.EchoHandler
  :methods [ #^{:static true} [handleEcho [org.rapidoid.http.Req] java.util.Map]] )
(defn -handleEcho ^Map [^Req req] (U/map (.headers req)))

Using it:

harrow.main=> (def config-get-route (http/set-http-get-route "/echo"))
harrow.main=> (import harrow.EchoHandler)
harrow.EchoHandler
harrow.main=> (.json config-get-route EchoHandler/handleEcho)

CompilerException java.lang.RuntimeException: Unable to find static field: handleEcho in class harrow.EchoHandler, compiling:(/private/var/folders/nr/g50ld9t91c555dzv91n43bg40000gn/T/form-init16236167396076700327.clj:1:1)

I am wondering what is the proper way of having a static method in Clojure.

2
  • First of all, you can not pass a static method as a function - you would have to wrap this in an anon-fn. Also I bet the java code there uses a single method interface and javac builds the handling class there for you. So you most likely have to reify the interface the json method expects. Commented Dec 11, 2018 at 20:39
  • Thanks for the info. Would you mind giving me an example? How to wrap this in an anon-fn? Thanks in advance! Commented Dec 11, 2018 at 21:25

1 Answer 1

4

First of all, you can not pass a static method as a function - you would have to wrap this in an anon-fn.

That aside, this would not work either, because this framework expects instances there implementing certain interfaces. Since Java8 you can write that as lambdas and the javac fills in the gaps for you, if the interface only has one method.

So you can not simply pass in a Clojure function, which implements e.g. IFn and Runnable, but not that specific interface needed there. So you would have to look up from the docs, whats allowed and reify.

E.g. with Rapidoid 5.5.5, it could look like this:

(ns try-rapidoid.core
  (:import (org.rapidoid.http ReqHandler)
           (org.rapidoid.setup On Setup)))

(def echo-route
  (doto
    (On/get "/echo")
    (.managed true)
    (.json (reify ReqHandler ; XXX
             (execute [this ^Object req]
               (.headers req))))))

#_(Setup/shutdownAll)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.