Расширение класса обслуживания Dropwizard в Clojure - PullRequest
3 голосов
/ 27 января 2012

Я уже некоторое время использую Dropwizard для написания API-интерфейсов RESTful в Scala, и мне бы очень хотелось использовать его в Clojure.

Я пытаюсь создать подкласс com.yammer.dropwizard.Service, который я могу создать и запустить в своем -main, и я изо всех сил стараюсь, чтобы это произошло.

Насколько я знаю, мои варианты:

  1. gen-class в ns декларации.Это невозможно, потому что я хочу создавать макросы (такие как defservice), которые я не могу использовать в объявлении ns.Если нет какого-либо способа сгенерировать вещь во время выполнения и передать ее compile, но это выглядит как грязный хак.
  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.Это кажется наиболее перспективным и работает для простых случаев, но не при расширении класса Service Dropwizard:

    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 чрезвычайно лаконичны.Как я могу расширить этот класс Java в Clojure?

1 Ответ

0 голосов
/ 27 января 2012

Я бы сказал, используйте вариант 1, но если я неправильно истолковываю ваше описание, похоже, вы пытаетесь написать код внутри формы пространства имен?Это не то, что вы хотите.Когда вы добавляете gen-класс в форму пространства имен, для всего этого пространства имен будет создан класс 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]
  ... )

Надеюсь, это поможет!

...