3

一段时间以来,我一直在使用 Dropwizard 在 Scala 中编写 RESTful API,我真的很想在 Clojure 中使用它。

我想要做的是创建一个子类com.yammer.dropwizard.Service,我可以在我的 中实例化和运行它-main,我正在努力实现这一点。

据我所知,我的选择是:

  1. gen-classns声明中。defservice不可行,因为我想构建不能在ns声明中使用的宏(例如)。除非有某种方法可以在运行时生成一个东西并将其传递给compile,但这似乎是一个肮脏的 hack。
  2. gen-class外面ns。尽管我找到了一些代码,但这似乎根本不起作用。这是一个简单的例子:

    user> (gen-class :name foo :extends Object)
    nil
    user> (foo.)
    Unable to resolve classname: foo
     [Thrown class java.lang.IllegalArgumentException]
    

    我知道这gen-class仅在编译时有效。我将它放入一个文件并放入(foo.-main的 . 中,我得到了同样的异常。

  3. proxy. 这似乎是最有希望的,它适用于简单的情况,但不适用于扩展 Dropwizard 的Service类:

    user> (proxy [Object] [])
    #<Object$0 user.proxy$java.lang.Object$0@249faafc>
    user> (import [com.yammer.dropwizard Service])
    com.yammer.dropwizard.Service
    user> (proxy [Service] ["x"])
    java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
      [Thrown class java.lang.ClassCastException]
    

    我认为这可能是由于Service采用了类型参数,但我在 Clojure 中找不到有关处理此问题的任何信息。我的发现似乎表明这些只对 javac 有意义,而被 Clojure 忽略。所以也许我对为什么会发生这种情况是不正确的。

  4. deftype. 不起作用,因为Service它是一个类,并且deftype仅适用于接口和协议。

我认为我走在正确的轨道上,但我错过了如何gen-class和/或proxy工作的一些微妙之处,而且 Clojure 文档非常简洁。如何在 Clojure 中扩展这个 Java 类?

4

1 回答 1

0

我会说使用选项 1,但除非我误解了您的描述,否则听起来您正在尝试在命名空间表单中编写代码?这不是你想要的。当您将 gen-class 添加到命名空间表单时,将为整个命名空间生成一个 Java 类。然后,您可以通过使用 -prefix 命名 ns 中的函数来覆盖方法(或选择另一个并使用 :method-prefix)。

这是一个例子。我对您使用这些类对其进行测试的库知之甚少,但它至少应该是相似的:

(ns com.myapp.MyService
  (:gen-class
   :extends com.yammer.dropwizard.Service
   :exposes-methods {someSuperClassMethod someLocalAlias}))

;; now just write your code as normal, note that
;; you can access super-class methods with the exposes-methods
;; map above!

;; prefix your overriden methods with -

(defn -overriddenMethod
  [params]
  ... )

希望有帮助!

于 2012-01-26T22:06:29.633 回答