Attaching metadata to a Clojure gen-class
Asked Answered
S

3

6

Is it possible to attach metadata to a Clojure gen-class?

I am trying to implement a server that uses a library that requires Java annotations added to classes.

From Chas Emerick's, et al., forthcoming book "Programming Clojure" (section 9.7.3), adding annotations to gen-class methods is easy, but there is no mention of adding class-level annotations.

Seaside answered 9/10, 2011 at 12:22 Comment(0)
B
24

Yes it is, I found a great example here:

https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/genclass/examples.clj

Here's some code inlined so it doesn't disappear in the future:

(gen-class :name ^{Deprecated {}
                   SuppressWarnings ["Warning1"] ; discarded
                   java.lang.annotation.Target []}
                 clojure.test_clojure.genclass.examples.ExampleAnnotationClass
           :prefix "annot-"
           :methods [[^{Deprecated {}
                        Override {}} ;discarded
                      foo [^{java.lang.annotation.Retention java.lang.annotation.RetentionPolicy/SOURCE
                             java.lang.annotation.Target    [java.lang.annotation.ElementType/TYPE
                                                             java.lang.annotation.ElementType/PARAMETER]}
                           String] void]])
Bimetallism answered 19/4, 2013 at 22:52 Comment(0)
P
1

I don't think it is possible at this point.

Rich Hickey mentions adding annotations support in this thread https://groups.google.com/group/clojure/browse_thread/thread/d2128e1505c0c117 but as far as I can see this is only for deftype / defrecord. I could be wrong of course.

Both of these

(ns genclass.example
  (:gen-class ^{:doc "example class"}))

and

(ns genclass.example)

(with-meta
  (gen-class
   :name genclass.example.ClassA
   :methods [[hello [] void]])
  {:doc "Example class"})      

fail to compile for me. From the exception

Exception in thread "main" java.lang.IllegalArgumentException: Metadata can only be applied to IMetas (example.clj:4)`

It sounds like this is not possible.

Phyllida answered 9/10, 2011 at 15:37 Comment(4)
I have started to use deftype instead of gen-class for my JAX-RS REST Server, following the example in Chas's book. It appears to be "cleaner".Seaside
You might also like the following flowchart, also by Chas: cemerick.com/2011/07/05/… It could be in his book, I don't have it yet...Phyllida
I saw the flowchart when it first showed up on twitter. Pretty nice! Thanks.Seaside
@Seaside could you be so kind and mark the other answer as the accepted one, as nowadays it is possible to attach annotations via gen-class.Overprize
B
1

To add additional information to this because I can't find it documented anywhere else it's possible to add annotations to constructors as well.

You can add annotations to constructors by adding meta data to the first array of the constructor pair. Like this:

(gen-class
  :name "FooClass"
  :init "init"
  :constructors {^{Inject {}} [Configuration] []}
  :state "state"
  :implements [FooInterface]
  :prefix "ref-")
Browband answered 9/6, 2016 at 4:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.