2012-01-26 52 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