This is probably a bug in the CXF JAXB Provider.  It's probably just grabbing 
the "raw" class files and not really looking for the XmlJavaTypeAdapter 
things.    Can you create a small test case and attach to a JIRA?

Dan


On Tuesday 15 June 2010 3:49:04 pm peter.giles wrote:
> Hello CXF cognoscenti,
> 
> I'm trying to get a test service working that uses an interface for my
> return type and am running into trouble.  I am under the possibly false
> impression that I should be able to get this to work using an
> @XmlJavaTypeAdapter (JAXB style -- see
> https://jaxb.dev.java.net/guide/Mapping_interfaces.html#Use__XmlJavaTypeAda
> pter). When I try to access my service I get "JAXBException occurred : 2
> counts of IllegalAnnotationExceptions. "  Here's the error from tomcat log
> with hopefully enough stack context:
> 
> Jun 15, 2010 11:59:14 AM org.apache.cxf.jaxrs.provider.AbstractJAXBProvider
> handleJAXBException
> WARNING: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts
> of IllegalAnnotationExceptions
> service.BaseballCard is an interface, and JAXB can't handle interfaces.
>       this problem is related to the following location:
>               at service.BaseballCard
> service.BaseballCard does not have a no-arg default constructor.
>       this problem is related to the following location:
>               at service.BaseballCard
> 
>       at
> com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Illeg
> alAnnotationsException.java:102) at
> com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.
> java:472) at
> com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302
> ) at
> com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBCo
> ntextImpl.java:1136) at
> com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
>       at
> com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:3
> 9) at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImp
> l.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
>       at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
>       at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
>       at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
>       at
> org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.getClassContext(Abstract
> JAXBProvider.java:351) at
> org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.getJAXBContext(AbstractJ
> AXBProvider.java:344) at
> org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.getJaxbQName(AbstractJAX
> BProvider.java:258) at
> org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.getCollectionWrapperQNam
> e(AbstractJAXBProvider.java:221) at
> org.apache.cxf.jaxrs.provider.JAXBElementProvider.marshalCollection(JAXBEle
> mentProvider.java:258) at
> org.apache.cxf.jaxrs.provider.JAXBElementProvider.writeTo(JAXBElementProvid
> er.java:233) at
> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRS
> OutInterceptor.java:241) *snip*
> 
> I thought this was what the type adapter was supposed to take care of -- do
> I need to do something special to point out the type adapter to CXF?  I
> apologize for the amount of code here, but I've stripped my test to the
> bare minimum.  Here it is:
> 
> @Path("/collection/") @Produces("application/xml")
> public interface BaseballCardCollectionService {
> 
>     @GET
>     public List<BaseballCard> getAll();
> 
>     @POST
>     @Path("/BaseballCard")
>     public Integer add(BaseballCard card);
> }
> 
> @XmlJavaTypeAdapter(BaseballCardImpl.BaseballCardAdapter.class)
> public interface BaseballCard {
> 
>     public String getPlayerName();
>     public String getCardType();
>     public Integer getYear();
> 
> }
> 
> @XmlRootElement
> public class BaseballCardImpl implements BaseballCard {
> 
>     private String cardType;
>     private String playerName;
>     private Integer year;
> 
>     public BaseballCardImpl() {}
> 
>     public BaseballCardImpl(String playerName, String cardType, Integer
> year) {
>         this.playerName = playerName;
>         this.cardType = cardType;
>         this.year = year;
>     }
> 
>     public void setCardType(String cardType) { this.cardType = cardType; }
>     public void setPlayerName(String playerName) { this.playerName =
> playerName; }
>     public void setYear(Integer year) { this.year = year; }
>     public String getCardType() { return cardType; }
>     public String getPlayerName() { return playerName; }
>     public Integer getYear() { return year; };
> 
>     public static class BaseballCardAdapter extends
> XmlAdapter<BaseballCardImpl, BaseballCard> {
> 
>         @Override
>         public BaseballCardImpl marshal(BaseballCard v) throws Exception {
>             return new BaseballCardImpl(v.getPlayerName(), v.getCardType(),
> v.getYear());
>         }
> 
>         @Override
>         public BaseballCard unmarshal(BaseballCardImpl v) throws Exception
> { return v; }
>     }
> }
> 
> public class BaseballCardCollectionServiceImpl implements
> BaseballCardCollectionService {
> 
>     private Map<Integer, BaseballCard> cards = new
> ConcurrentHashMap<Integer, BaseballCard>();
>     private AtomicInteger nextId = new AtomicInteger(1);
> 
>     public BaseballCardCollectionServiceImpl() {
>         add(new BaseballCardImpl("Leroy Paige", "Leaf", 1949));
>     }
> 
>     public Integer add(BaseballCard card) {
>         Integer result = null;
>         if (card != null) {
>             int id = nextId.addAndGet(1);
>             cards.put(id, card);
>             result = id;
>         }
>         return result;
>     }
> 
>     public List<BaseballCard> getAll() {
>         return new ArrayList<BaseballCard>(cards.values());
>     }
> 
> }
> 
> Here is the important part of my spring config:
> 
>     <import resource="classpath:META-INF/cxf/cxf.xml" />
>     <import
> resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
>     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
> 
>     <jaxrs:server id="collectionService" address="/">
>         <jaxrs:serviceBeans>
>             <ref bean="collectionImpl" />
>         </jaxrs:serviceBeans>
>         <jaxrs:extensionMappings>
>             <entry key="xml" value="application/xml" />
>         </jaxrs:extensionMappings>
>     </jaxrs:server>
> 
>     <bean id="collectionImpl"
> class="service.BaseballCardCollectionServiceImpl" />
> 
> The URL I'm hitting for my service is
> http://localhost:8080/cxf-rest-example/collection/ which gives me the short
> version of the error message.  I can see the wadl at
> http://localhost:8080/cxf-rest-example/collection?_wadl&_type=xml but I
> must admit that I don't know anything about wadl so I am not getting any
> clues from it:
> 
> <application>
>  <grammars/>
>   <resources base="http://localhost:8080/cxf-rest-example/";>
>    <resource path="/collection/">
>     <method name="GET">
>      <response>
>       <representation mediaType="application/xml"/>
>      </response>
>     </method>
>     <resource path="BaseballCard">
>      <method name="POST">
>       <request>
>        <representation mediaType="*/*"/>
>       </request>
>       <response>
>        <!-- Primitive type : xs:int -->
>        <representation mediaType="application/xml"/>
>       </response>
>     </method>
>    </resource>
>   </resource>
>  </resources>
> </application>
> 
> Does anybody see what am I doing wrong?
> 
> Thank you!
> Peter Giles

-- 
Daniel Kulp
[email protected]
http://dankulp.com/blog

Reply via email to