我试图从Clojure调用Java方法。它具有某种类型的参数。
我已经使用reify创建了一个子类并重写了一个方法。当我尝试调用Java方法时,收到IllegalArgumentsException。我已经使用clojure.reflect来确认该方法是否存在,所以我认为问题在于它无法识别该子类。
这是我的project.clj:
(defproject clojure-se "0.1.0-SNAPSHOT"
:description "A clojure Helidon SE app"
:dependencies [[org.clojure/clojure "1.9.0"]
[io.helidon/helidon-bom "1.0.0" :extension "pom"]
[io.helidon.bundles/helidon-bundles-webserver "1.0.0"]
[io.helidon.config/helidon-config-yaml "1.0.0"]
[io.helidon.health/helidon-health "1.0.0"]
[io.helidon.health/helidon-health-checks "1.0.0"]
[io.helidon.metrics/helidon-metrics "1.0.0"]] :main ^:skip-aot clojure-se.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
我的代码:
(ns clojure-se.core
(:gen-class)
(:import io.helidon.webserver.Routing
io.helidon.webserver.Routing$Builder
io.helidon.webserver.Handler
io.helidon.webserver.ServerRequest
io.helidon.webserver.ServerResponse
io.helidon.webserver.WebServer))
(defn -main
"I am a Helidon app."
[& args]
(def handler (reify io.helidon.webserver.Handler
(^void accept [this ^ServerRequest req ^ServerResponse res]
(print "handled a request"))))
(def builder (. Routing builder))
(def routing (.any builder handler))
; also tried:
; (def routing (.any builder "/test" handler))
; to use the method with String, Handler
; (def routing (.any builder (to-array '(handler)))
; to use the method with Handler... (varargs)
(def server
(. WebServer create routing))
(. server start))
作为参考,下面是大致等效的Java代码:
public static void main (String[] args) throws Exception {
WebServer webServer = WebServer.create (Routing.builder()
.any ((req, res) -> res.send ("It works!"))
.build())
.start();
}
any()的参数是处理程序,FunctionalInterface
我可以在反射输出中看到这些方法:
clojure-se.core=> (pprint (reflect builder))
{:bases
#{java.lang.Object io.helidon.webserver.Routing$Rules
io.helidon.common.Builder},
:flags #{:public},
:members
#{ ; truncated...
{:name any,
:return-type io.helidon.webserver.Routing$Builder,
:declaring-class io.helidon.webserver.Routing$Builder,
:parameter-types [io.helidon.webserver.Handler<>],
:exception-types [],
:flags #{:varargs :public}}
{:name any,
:return-type io.helidon.webserver.Routing$Builder,
:declaring-class io.helidon.webserver.Routing$Builder,
:parameter-types [java.lang.String io.helidon.webserver.Handler<>],
:exception-types [],
:flags #{:varargs :public}}}
这是我得到的例外,请注意,如果我在REPL中查看handler
,它说它是一个验证,而不是Handler,尽管反射确实显示它是以Handler为基础。
clojure-se.core=> (-> (. Routing builder) (.any handler) (.build))
IllegalArgumentException No matching method found: any for class io.helidon.webserver.Routing$Builder clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
clojure-se.core=> handler
#object[clojure_se.core$reify__1772 0x109a9c90 "clojure_se.core$reify__1772@109a9c90"]
clojure-se.core=>