2012-01-26 9 views
3

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

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

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

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

  4. deftype. Не работает, потому что Service является классом, а deftype работает только с интерфейсами и протоколами.

Я думаю, что я нахожусь на правильном пути, но не хватает некоторых тонкостей, как gen-class и/или proxy работы и документация Clojure крайне лаконична. Как я могу расширить этот класс Java в Clojure?

+0

Clojure обычно может проксировать объект, который принимает общие параметры (try '(proxy [java.util.ArrayList] [])'). Ваша текущая проблема связана с реализацией 'com.yammer.dropwizard.AbstractService' и особенно вызова' getConfigurationClass' внутри конструктора. На основе быстрого просмотра иерархия классов Dropwizard кажется очень странной. – ponzao

ответ

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^