3

I am trying to use a Spring Wadl Generator: https://github.com/autentia/wadl-tools.

AFAIK, this tool uses the same idea of the Tomasz Nurkiewicz @tomasz-nurkiewicz: get the RequestMappingHandlerMapping from Spring, inspect each element and generate a appropriate WADL.

Internally, the tool will use JAXB to create an XML of the parameters in controllers. As far as good, but things doesn't run nicely with my application.

I got the following exception:

2014-02-07 15:33:41,827 WARN  user=unauthenticatedUser com.autentia.xml.namespace.QNameBuilder  - Cannot discover QName from JAXB annotations for class: java.util.Map. Preparing generic QName.com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.util.Map is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at java.util.Map

Which comes from (simplified stacktrack)

at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:106)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:471)
    (...)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
    (...)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at com.autentia.xml.namespace.QNameBuilder.discoverQNameFromJaxb(QNameBuilder.java:68)
    (...)
at com.autentia.web.rest.wadl.builder.ApplicationBuilder.build(ApplicationBuilder.java:36)

The question

Could I force a default adapter to an Interface?

Normally people can just put annotations for interface with specific Adapter but I don't wanna change and/or analyze hundred of classes.

Related links

Edited

Unfortunately I cannot change REST API.

From javadoc of MessageWriter:

Contract for a provider that supports the conversion of a Java type to a stream. To add a MessageBodyWriter implementation, annotate the implementation class with @Provider.

WADL should provide info of services as they are. Adding a MessageBodyWriter via annotation for example would change the API. Since I can change QNameBuilder.discoverQNameFromJaxb, would there be possible change/provide in this very "moment" the MessageBodyWriter to java.util.Map and change back WADL generation?

Community
  • 1
  • 1
rdllopes
  • 4,897
  • 4
  • 19
  • 36

1 Answers1

3

What's Causing the Problem

JAXB (JSR-222) implementations can handle java.util.Map as a mapped field/property, but can not handle it as a root level object. You probably have a method corresponding to a RESTful operation that returns to takes a Map.

How to Solve It

  1. Instead of having Map as the root level object you could introduce a new domain object that has a mapped field/property of type Map and use that instead.
  2. Implement a MessageBodyReader/MessageBodyWriter for the Map class so that will be used instead of JAXB being used.

UPDATE

I don't wanna change and analyze hundred of classes

You wouldn't be. You would simply be adding a MessageBodyReader/MessageBodyWriter that recognizes the Map class (for the "application/xml" media type) to do special handling for it. The alternative is to keep getting an exception.

Basically I cannot change the REST API.

You wouldn't be changing the REST API. You would need to ensure that your MessageBodyReader/MessaggeBodyWriter works appropriately.

By using a low level of dark magic, would be possible supply a MessageBodyWriter for the Map and remove after that?

It's not really all that low level or dark magic. You can supply special handling just for the Map class.

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Unfortunately I cannot change REST API. WADL should provide info of services as they are. (I will add more info in question). – rdllopes Feb 10 '14 at 14:58
  • I've updated the question making more clear what I mean by " I don't wanna change and analyze hundred of classes". Basically I cannot change the REST API. By using a low level of dark magic, would be possible supply a MessageBodyWriter for the Map and remove after that? – rdllopes Feb 10 '14 at 15:33
  • @blaise.doughan - as long as go deep this I realize how complicated it could be. I am using Spring MVC that AFAIK, out of box it will not identify \@Provider Annotation (Actually, JSR 311 which contains MessageBodyWriter it was currently in CLASSPATH also). – rdllopes Feb 10 '14 at 17:08
  • The big issue about that solution is the @Provider annotation. I need to add JSR 311 + provide a way to Spring understand this annotation. – rdllopes Feb 17 '14 at 08:50