9

I'm working on the implementation of various REST services, using Spring MVC. For documentation, I'm using Swagger.

This works nice and the documentation looks good and is really functional. The only problem I have is that the annotations for documentation really crowd the controller classes, especially the error code annotations.

Example:

@ApiErrors(value = {
    @ApiError(code = 123, reason = "Reason123"),
    @ApiError(code = 124, reason = "Reason124"),
    @ApiError(code = 125, reason = "Reason125"),
    @ApiError(code = 126, reason = "Reason126"),
    @ApiError(code = 127, reason = "Reason127") })
public void exampleFunctionImplementation() {
}

In many cases, this leads to large blocks of annotations where the real application code is hidden somewhere in between. In addition, this annotation sets are often repeated, as a lot of methods may return the same set of error codes.

Is there any option to shorten this a bit through defining the annotation list somewhere else as a constant in another class file? Or maybe something even more simple I may have overlooked?

I tried with defining the array of @ApiError items somewhere, but this won't compile:

ApiError[] array = {ApiError(code = 123, reason = "Reason123")};

I would be glad if anybody could give me a hint how to solve this problem, thanks in advance!

Volker
  • 450
  • 5
  • 16
  • Both of you have the same problem: http://stackoverflow.com/questions/14195155/ibatis-create-an-array-of-multiple-annotations-annotation-reuse – Anderson Jan 14 '14 at 07:48

1 Answers1

1

Annotation members have only limited types (JLS 9.6).

It is a compile-time error if the return type of a method declared in an annotation type is not one of the following: a primitive type, String, Class, any parameterized invocation of Class, an enum type (§8.9), an annotation type, or an array type (§10) whose element type is one of the preceding types.

Their values must be constant expressions (JLS 9.7). The standard uses the term commensurate.

T is an array type E[] and either:

V is an ElementValueArrayInitializer and each ElementValue (analogous to a VariableInitializer in an array initializer) in V is commensurate with E; or

V is an ElementValue that is commensurate with E.

The type of V is assignment compatible (§5.2) with T, and furthermore:

If T is a primitive type or String, and V is a constant expression (§15.28).

V is not null.

If T is Class, or an invocation of Class, and V is a class literal (§15.8.2).

If T is an enum type, and V is an enum constant.

Your array is not a constant expression, so your code won't compile. If you anticipate having large annotation lists, perhaps there is another way to do this task. I don't know Swagger, so you might not be able to avoid this, however.

Community
  • 1
  • 1
Eric Jablow
  • 7,874
  • 2
  • 22
  • 29
  • 2
    What a pity - somehow, I hoped there would be a clever way around this to somehow reuse a set of annotations :-( – Volker Jun 17 '13 at 10:04
  • Java 8 will help. See http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html – Eric Jablow Jun 17 '13 at 10:22
  • 2
    @EricJablow, this new feature is nice but it won't help. Because topic starter doesn't want to duplicate the annotations between the methods. He wants rather to define the cumbersome annotation once and apply it to other methods. I have kinda same problem with Swagger. – walv Mar 21 '16 at 19:22