2012-01-26 54 views
3

我一直在使用Dropwizard在Scala中编写RESTful API一段时间,我真的很想在Clojure中使用它。在Clojure中扩展Dropwizard服务类

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

所以,据我所知,我的选择是:

  1. gen-classns声明。不可行,因为我想构建宏,例如defservice,在ns声明中我不能使用这些宏。除非有什么方法可以在运行时生成一个东西并将它传递给compile,但这看起来像是一个肮脏的黑客。
  2. gen-class outside ns。尽管some code I found,似乎这根本不起作用。这里有一个简单的例子:

    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 [email protected]> 
    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类?

+0

Clojure通常可以代理一个需要通用参数的对象(尝试'(proxy [java.util.ArrayList] [])')。你目前的问题是由于'com.yammer.dropwizard.AbstractService'的实现,特别是在构造函数中对'getConfigurationClass'的调用。 基于快速查看,Dropwizard的类层次结构看起来很奇怪。 – ponzao

回答

0

我会说使用选项1,但除非我误解了你的描述,这听起来像你试图在命名空间窗体内编写代码?这不是你想要的。当您将一个gen-class添加到名称空间表单中时,将为该整个名称空间生成一个Java类。然后,您可以通过在ns中用-prefix命名函数(或者选择另一个函数并使用: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] 
    ...) 

希望帮助!

+0

这个问题的主要问题是它需要服务的作者将样板放到他们的(ns ...)中。我想要的是有'defservice'来生成适当的'gen-class'(或其他)。我想这种方法是可以接受的,如果它是唯一能够工作的方法,但它远没有我想要的那样。 – ieure