You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by ermedeiros <el...@yahoo.com.br> on 2010/07/21 20:57:28 UTC

Re: JAX-RS service w/ interface result type, @XmlJavaTypeAdapter

Hi Sergey,

the workaround does not work for me: If I try to add @XmlJavaTypeAdapter as
a method annotation I get the same Exception (IllegalAnnotationExceptions)
and if I try to add @XmlJavaTypeAdapter in the implementation class I get a
".No message body writer found" message.

In addition, I only have problems with Collection or List parameters/return
type. For example, a method like:

@GET
public BaseballCard getBaseballCard();

works fine, but a method like:

@GET
 public List<BaseballCard> getAll()

throws the famous IllegalAnnotationExceptions.

Thanks,
Elias
-- 
View this message in context: http://cxf.547215.n5.nabble.com/JAX-RS-service-w-interface-result-type-XmlJavaTypeAdapter-tp564352p1750090.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: JAX-RS service w/ interface result type, @XmlJavaTypeAdapter

Posted by Sergey Beryozkin <sb...@gmail.com>.
Thanks - I'll get the fix applied

Sergey

On Fri, Jul 23, 2010 at 8:38 PM, ermedeiros <el...@yahoo.com.br> wrote:

>
> Hi Sergey,
>
> I think I found the bug: in the method JAXBElementProvider.writeTo it's
> necessary to add a call to AbstractJAXBProvider.getActualType(Class<?>
> type,
> Type genericType, Annotation[] anns) before calling marshalCollection
> method.
>
> I created a new class that extends JAXBElementProvider and orverwrites
> writeTo method. I've just added the line below to solve the problem.
> actualClass = getActualType(actualClass, genericType, anns);
>
>
> See the code below:
>
>
> public class MyJAXBElementProvider extends JAXBElementProvider{
>
>        public void writeTo(Object obj, Class<?> cls, Type genericType,
> Annotation[] anns,
>                MediaType m, MultivaluedMap<String, Object> headers,
> OutputStream
> os)
>                throws IOException {
>                try {
>                    Object actualObject = checkAdapter(obj, cls, anns,
> true);
>                    Class<?> actualClass = obj != actualObject ?
> actualObject.getClass() : cls;
>                    String encoding = HttpUtils.getSetEncoding(m, headers,
> null);
>                    if
> (InjectionUtils.isSupportedCollectionOrArray(actualClass)) {
>                        actualClass =
> InjectionUtils.getActualType(genericType);
>
>                        /*  added ***********************************/
>                            actualClass = getActualType(actualClass,
> genericType, anns);
>                                /* ****************************************/
>
>                        marshalCollection(cls, actualObject, actualClass,
> genericType, encoding, os, m);
>                    } else {
>                        marshal(actualObject, actualClass, genericType,
> encoding,
> os, m);
>                    }
>                } catch (JAXBException e) {
>                    handleJAXBException(e);
>                }  catch (WebApplicationException e) {
>                    throw e;
>                } catch (Exception e) {
>                    throw new WebApplicationException(e);
>                }
>            }
> }
>
>
> I think the same change is necessary for JSONProvider.
>
> Regards,
> Elias
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/JAX-RS-service-w-interface-result-type-XmlJavaTypeAdapter-tp564352p1861836.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>

Re: JAX-RS service w/ interface result type, @XmlJavaTypeAdapter

Posted by ermedeiros <el...@yahoo.com.br>.
Hi Sergey,

I think I found the bug: in the method JAXBElementProvider.writeTo it's
necessary to add a call to AbstractJAXBProvider.getActualType(Class<?> type,
Type genericType, Annotation[] anns) before calling marshalCollection
method.

I created a new class that extends JAXBElementProvider and orverwrites
writeTo method. I've just added the line below to solve the problem.
actualClass = getActualType(actualClass, genericType, anns);


See the code below:


public class MyJAXBElementProvider extends JAXBElementProvider{
	
	public void writeTo(Object obj, Class<?> cls, Type genericType,
Annotation[] anns,  
	        MediaType m, MultivaluedMap<String, Object> headers, OutputStream
os) 
	        throws IOException {
	        try {
	            Object actualObject = checkAdapter(obj, cls, anns, true);
	            Class<?> actualClass = obj != actualObject ?
actualObject.getClass() : cls;
	            String encoding = HttpUtils.getSetEncoding(m, headers, null);
	            if (InjectionUtils.isSupportedCollectionOrArray(actualClass)) {	            	
	            	actualClass = InjectionUtils.getActualType(genericType);
	            	
	            	/*  added ***********************************/ 
		            actualClass = getActualType(actualClass, genericType, anns);
		        	/* ****************************************/	            	                               
	                
	                marshalCollection(cls, actualObject, actualClass,
genericType, encoding, os, m);
	            } else {
	                marshal(actualObject, actualClass, genericType, encoding,
os, m);
	            }
	        } catch (JAXBException e) {
	            handleJAXBException(e);
	        }  catch (WebApplicationException e) {
	            throw e;
	        } catch (Exception e) {
	            throw new WebApplicationException(e);        
	        }
	    }	
}


I think the same change is necessary for JSONProvider.

Regards,
Elias
-- 
View this message in context: http://cxf.547215.n5.nabble.com/JAX-RS-service-w-interface-result-type-XmlJavaTypeAdapter-tp564352p1861836.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: JAX-RS service w/ interface result type, @XmlJavaTypeAdapter

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Elias

There's a test on the trunk (systests/jaxrs) (JAXRSClientServerBook &
BookServer) showing that adapters attached to interfaces work (as well as to
JAXRS methods).

Explicit collection of interfaces with adapters involved - I'm not surprised
it does not work.
I think the collectionsMap just plainly checks for the equality, so as a
workaround use the impl class name.

You said returning just an interface works. So there's some bug in the way
explicit collection of interfaces is handled. I wish I could look into it
but unless you can help with some debugging, I can't prioritize at the
moment on the issues for which workarounds exist

thanks, Sergey

On Fri, Jul 23, 2010 at 5:10 PM, ermedeiros <el...@yahoo.com.br> wrote:

>
> Hi Sergey,
>
> Thanks for your help.
> Introduce a simple public BaseballCardCollection bean isn't a relly option
> for me. I tried with a collectionWrapperMap property, but I got some
> problems. First of all, must I use the interface or the implemation name in
> <key><value>...</value></key>?
>
> when I try:
>
> <bean id="jaxbProvider"
> class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
>        <property name="collectionWrapperMap">
>                <map>
>                    <entry>
>                      <key><value>mypackage.MyInterface</value></key>
>                      <value>MyObjects</value>
>                    </entry>
>                 </map>
>         </property>
>  </bean>
>
> I get:
> "Unexpected EOF; was expecting a close tag for element <MyObjects>"
>
> and when I try:
>
>   <bean id="jaxbProvider"
> class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
>        <property name="collectionWrapperMap">
>                <map>
>                    <entry>
>                      <key><value>mypackage.MyImplementation</value></key>
>                      <value>MyObjects</value>
>                    </entry>
>                 </map>
>         </property>
>  </bean>
>
> I get:
> "WARNING: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts
> of Il
> legalAnnotationExceptions
> mypackage.MyInterface is an interface, and JAXB can't handle inter
> faces.
>        this problem is related to the following location:
>                at mypackage.MyInterface
> demo.jaxrs.server.CustomerInterface does not have a no-arg default
> constructor.
>        this problem is related to the following location:
>                at mypackage.MyInterface
> "
>
> Last remark: I'm getting the fixed version from
> https://repository.apache.org/content/groups/snapshots-group
>        <dependency>
>            <groupId>org.apache.cxf</groupId>
>            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
>            <version>2.2.10-SNAPSHOT</version>
>        </dependency>
>
> Is that right?
> Thanks again,
> Elias
>
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/JAX-RS-service-w-interface-result-type-XmlJavaTypeAdapter-tp564352p1843475.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>

Re: JAX-RS service w/ interface result type, @XmlJavaTypeAdapter

Posted by ermedeiros <el...@yahoo.com.br>.
Hi Sergey,

Thanks for your help.
Introduce a simple public BaseballCardCollection bean isn't a relly option
for me. I tried with a collectionWrapperMap property, but I got some
problems. First of all, must I use the interface or the implemation name in
<key><value>...</value></key>?

when I try:

<bean id="jaxbProvider"
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
	<property name="collectionWrapperMap">
	        <map>
		    <entry>
		      <key><value>mypackage.MyInterface</value></key>
		      <value>MyObjects</value>
		    </entry>
		 </map>
	 </property>		
  </bean>

I get:
"Unexpected EOF; was expecting a close tag for element <MyObjects>"

and when I try:

   <bean id="jaxbProvider"
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
	<property name="collectionWrapperMap">
	        <map>
		    <entry>
		      <key><value>mypackage.MyImplementation</value></key>
		      <value>MyObjects</value>
		    </entry>
		 </map>
	 </property>		
  </bean>

I get:
"WARNING: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts
of Il
legalAnnotationExceptions
mypackage.MyInterface is an interface, and JAXB can't handle inter
faces.
        this problem is related to the following location:
                at mypackage.MyInterface
demo.jaxrs.server.CustomerInterface does not have a no-arg default
constructor.
        this problem is related to the following location:
                at mypackage.MyInterface
"

Last remark: I'm getting the fixed version from
https://repository.apache.org/content/groups/snapshots-group 
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>2.2.10-SNAPSHOT</version>
        </dependency>

Is that right?
Thanks again,
Elias

-- 
View this message in context: http://cxf.547215.n5.nabble.com/JAX-RS-service-w-interface-result-type-XmlJavaTypeAdapter-tp564352p1843475.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: JAX-RS service w/ interface result type, @XmlJavaTypeAdapter

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Elias

So it is this one

> public List<BaseballCard> getAll()

which does not work...

Given BaseballCard's representation is 'resolved' through the adapter, the
reason the above does not work is that
JAXBElementProvider can not figure out what the collection element name
should be.
Either introduce a simple BaseballCardCollection bean or try experimenting
with a collectionWrapperMap property :
http://cxf.apache.org/docs/jax-rs.html#JAX-RS-Handlingexplicitcollections

hope it helps, Sergey





On Wed, Jul 21, 2010 at 7:57 PM, ermedeiros <el...@yahoo.com.br> wrote:

>
> Hi Sergey,
>
> the workaround does not work for me: If I try to add @XmlJavaTypeAdapter as
> a method annotation I get the same Exception (IllegalAnnotationExceptions)
> and if I try to add @XmlJavaTypeAdapter in the implementation class I get a
> ".No message body writer found" message.
>
> In addition, I only have problems with Collection or List parameters/return
> type. For example, a method like:
>
> @GET
> public BaseballCard getBaseballCard();
>
> works fine, but a method like:
>
> @GET
>  public List<BaseballCard> getAll()
>
> throws the famous IllegalAnnotationExceptions.
>
> Thanks,
> Elias
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/JAX-RS-service-w-interface-result-type-XmlJavaTypeAdapter-tp564352p1750090.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>