cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From diana allam <allamcxfu...@gmail.com>
Subject Re: How to configure cxf to use MOXY Jaxb for RESTful
Date Fri, 22 Feb 2013 14:32:05 GMT
Hello Sergey,

Here is my test on a simple GET service example in a project with interface
+ implementation classes:


@XmlSeeAlso({MyObjectFactory.class})
@Path("/service/")
public interface ServiceInterface {

    @GET
    @Path("/resources/{id}/")
    public Resource getResource(@PathParam("id") int id);
}


-------------------------------------------------------------------------------------
@XmlSeeAlso({MyObjectFactory.class})
@Path("/service/")
public class Service implements ServiceInterface {
    Map<Integer, Resource> resources= new HashMap<Integer, Resource>();

    public Service(){

        Resource r = new ResourceImpl1();

        this.resources.put(r.getId(), r);


    }

    @GET
    @Path("/resources/{id}/")
    public Resource getResource(@PathParam("id") int id) {
        System.out.println(this.resources.get(id).printInfo() );
        return this.resources.get(id);
    }


}

----------------------------------------------------------------------------------

@XmlRegistry
public class MyObjectFactory {


     public MyObjectFactory() {
        }


    public Resource createResource() {
       // return createInstance(Resource.class);
        return createInstance(Resource.class);
        //return new ResourceImpl1();
    }




    private <T> T createInstance(Class<T> anInterface) {
        return (T) Proxy.newProxyInstance(anInterface.getClassLoader(), new
Class[] {anInterface}, new InterfaceInvocationHandler());
    }

   private static class InterfaceInvocationHandler implements
InvocationHandler {

        private Map<String, Object> values = new HashMap<String, Object>();

        public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
            String methodName = method.getName();
            if(methodName.startsWith("get")) {
                return values.get(methodName.substring(3));

            }
            else {
                values.put(methodName.substring(3), args[0]);
                return null;
            }
        }

    }

}
-------------------------------------------------------------------------------------------------
@XmlSeeAlso({ResourceImpl1.class, ResourceImpl2.class,
MyObjectFactory.class})
@XmlRootElement(name = "Resource")
@XmlType(propOrder={"name", "info"})
public interface Resource {

    public int getId();
    public void setId(int id);
    public String getName();
    public void setName(String name);
    public String printInfo();

}
----------------------------------------------------------------------------------

@XmlRootElement(name = "ResourceImpl1")
public class ResourceImpl1 implements Resource{

    private int id;
    private String name;

    public ResourceImpl1(int id, String name){
        this.name=name;
    }

    public ResourceImpl1(){
        this(0, "Impl1-default");
    }
    public String getName() {
        // TODO Auto-generated method stub
        return this.name;
    }

    public void setName(String name) {
        // TODO Auto-generated method stub
        this.name=name;
    }

    public String printInfo() {
        // TODO Auto-generated method stub
        return "This is a ResourceImpl1, id: " + this.id +  "name: " +
this.name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
-------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="
http://cxf.apache.org/jaxrs"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
      <import resource="classpath:META-INF/cxf/cxf.xml" />
      <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    <jaxrs:server id="test" address="/">
        <jaxrs:serviceBeans>
            <ref bean="myWebService" />
        </jaxrs:serviceBeans>
        <jaxrs:providers>
                        <ref bean="MOXYProvider" />
        </jaxrs:providers>
    </jaxrs:server>
    <bean id="MOXYProvider" class="commun.MoxyJaxbContextResolver" />
    <bean id="myWebService" class="server.Service" />
</beans>
---------------------------------------------------------------------------------

@Provider
public class MoxyJaxbContextResolver implements
ContextResolver<JAXBContext> {

    public JAXBContext getContext(Class<?> type) {
        try {
            JAXBContext jc = JAXBContextFactory.createContext(new Class[]
{Resource.class}, null);

            return jc;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }

}

----------------------------------------------------------------------------

I get the following error when I try to call my get method from the
browser, by typing:
http://localhost:8080/rs-testServiceWithInterfaces1/service/resources/0
--------------------------
XML Parsing Error: syntax error
Location:
http://localhost:8080/rs-testServiceWithInterfaces1/service/resources/0
Line Number 1, Column 1:Error serializing the response, please check the
server logs, response class : ResourceImpl1
---------------------------
At the server, I get the following exceptions:
java.lang.NoClassDefFoundError:
org/eclipse/persistence/jaxb/JAXBContextFactory
    at
commun.MoxyJaxbContextResolver.getContext(MoxyJaxbContextResolver.java:16)
    at
commun.MoxyJaxbContextResolver.getContext(MoxyJaxbContextResolver.java:1)
    at
org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.getJAXBContext(AbstractJAXBProvider.java:362)
    at
org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.createMarshaller(AbstractJAXBProvider.java:476)
    at
org.apache.cxf.jaxrs.provider.JAXBElementProvider.marshal(JAXBElementProvider.java:349)
    at
org.apache.cxf.jaxrs.provider.JAXBElementProvider.writeTo(JAXBElementProvider.java:237)
    at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:257)
    at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:144)
    at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:83)
    at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)
    at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:206)
    at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:218)
    at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:161)
    at
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:114)
    at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:184)
    at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:112)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:163)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.ClassNotFoundException:
org.eclipse.persistence.jaxb.JAXBContextFactory
    at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
    at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
    ... 37 more
Feb 22, 2013 3:24:42 PM
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
writeResponseErrorMessage
WARNING: Error serializing the response, please check the server logs,
response class : ResourceImpl1.


Regards,
Diana


On Thu, Feb 21, 2013 at 11:17 AM, Sergey Beryozkin <sberyozkin@gmail.com>wrote:

> Hi Diana,
>
> On 21/02/13 10:05, diana allam wrote:
>
>> Hello,
>>
>> I would like just to add more information about the utility of using
>> interfaces in cxf without implementation classes.
>> For my previous example about Resource, ResourceImpl1 and ResourceImpl2,
>> my
>> proposed solution by using an adapter of Resource class in order to allow
>> JAXB to use interfaces is not a very nice solution.
>> It will be nice if for example I define three interfaces, Resource,
>> Resource1 and Resource2, while Resource1 and Resource2 extends Resource.
>> That way, by using MOXY, I can avoid the use of adapters and I can
>> distinguish the treatment of messages at reception according to Resource1
>> or Resource2 types. This approach is very similar to what is actually
>> possible in cxf when for example a subclass instance is sent to a service
>> waiting a superclass of it.
>>
>> Can somebody help me to find the way to do it in cxf please?
>>
>>  I'd like to help but at the moment I'm still not sure where exactly the
> problem is :-). I'd like to propose to simplify the setup a bit in order to
> narrow down the issue.
>
> Can you please type a single root resource, with a single @GET method, the
> way you'd expect it to be in your project (interface + implementation, or
> just implementation) and also type a very basic JAXB Bean class, with
> @XMLRootElement, register Moxy-aware ContextResolver and access this method
> from a browser - will you get it working ?
>
> If yes - try the same with a CXF RS code, just make sure you also register
> Moxy-aware ContextResolver on the client side, and try to read the response
> there - this should work too.
>
> Can you try the above first please and if that works - then lets move to
> your current issue, if not - lets try to figure out first why the simple
> case does not work
>
> Cheers, Sergey
>
>
>  Regards,
>>
>> Diana
>>
>>
>>
>> On Wed, Feb 20, 2013 at 6:22 PM, diana allam<allamcxfuser@gmail.com>
>>  wrote:
>>
>>  thanks for your fast reply.
>>> I tested it because actually I am interested in deploying services with
>>> an
>>> interface type as input or output.
>>> I already tested on cxf how to do it by using implementation classes, for
>>> example, I defined a Resource interface and two implementations
>>> ResourceImpl1 and ResourceImpl2 such that all my REST methods are
>>> declared
>>> with a Resource type and I consider to differentiate the treatment at a
>>> reception of a ResourceImpl1 or ResourceImpl2. In order to do that I
>>> added
>>> the following two annotations to my Resource interface, and my
>>> AdaptedResource class (which is the adapted java instance for
>>> serialization
>>> and deserialization) contains an attribute which refers to the
>>> corresponding implementation (ResourceImpl1 or ResourceImpl2).
>>>
>>> ------------------------------**------------------------------**
>>> ------------------------
>>> @XmlSeeAlso({ResourceImpl1.**class, ResourceImpl2.class})
>>> @XmlJavaTypeAdapter(**MyResourceAdapter.class)
>>> public interface Resource {...}
>>>
>>> ------------------------------**------------------------------**
>>> ------------------------
>>>
>>>
>>> By curiosity, I tested MOXY without implementation classes and it works,
>>> but not for cxf, I didn't understand the problem
>>>
>>>
>>> On Wed, Feb 20, 2013 at 5:59 PM, Sergey Beryozkin<sberyozkin@gmail.com**
>>> >wrote:
>>>
>>>  Hi
>>>>
>>>> The appears to be some issue with your invocation handler, why do you
>>>> need it all ? If users had to write InvocationHandlers in order to be
>>>> able
>>>> to work with CXF RS client runtime then it would not be ideal at all :-)
>>>>
>>>> Thanks, Sergey
>>>>
>>>>
>>>> On 20/02/13 16:49, allam-di wrote:
>>>>
>>>>  Hello all,
>>>>>
>>>>> I would like to use MOXY in order to handle interfaces as input
>>>>> arguments on
>>>>> my service methods.
>>>>> First, I tested MOXY data binding with interfaces as it is given in the
>>>>> following blog:
>>>>> http://blog.bdoughan.com/2010/****07/moxy-jaxb-map-interfaces-****<http://blog.bdoughan.com/2010/**07/moxy-jaxb-map-interfaces-**>
>>>>> to-xml.html<http://blog.**bdoughan.com/2010/07/moxy-**
>>>>> jaxb-map-interfaces-to-xml.**html<http://blog.bdoughan.com/2010/07/moxy-jaxb-map-interfaces-to-xml.html>
>>>>> >
>>>>>
>>>>>
>>>>> It works oK for me, thus I can serialize and deserialize messages by
>>>>> declaring a service method with an interface argument, without defining
>>>>> any
>>>>> implementation classes of this interface.
>>>>> In order to do a similar think integrated to cxf, I followed the
>>>>> discussion
>>>>> at this link:
>>>>> http://cxf.547215.n5.nabble.****com/How-to-configure-CXF-to-**
>>>>> use-different-****JAXBContextFactory-td5281773.****html<
>>>>> http://cxf.547215.n5.**nabble.com/How-to-configure-**
>>>>> CXF-to-use-different-**JAXBContextFactory-td5281773.**html<http://cxf.547215.n5.nabble.com/How-to-configure-CXF-to-use-different-JAXBContextFactory-td5281773.html>
>>>>> >
>>>>>
>>>>>
>>>>> Here is my ContextResolver Class:
>>>>> ------------------------------****-----------
>>>>>
>>>>>
>>>>> package project;
>>>>>
>>>>> @Provider
>>>>> public class MyContextResolver implements ContextResolver<JAXBContext>
>>>>>   {
>>>>>       private JAXBContext jc;
>>>>>
>>>>>       public MyContextResolver() {
>>>>>          try {
>>>>>
>>>>>               jc = JAXBContext.newInstance(****MyObjectFactory.class);
>>>>>
>>>>>           } catch(JAXBException e) {
>>>>>               throw new RuntimeException(e);
>>>>>           }
>>>>>       }
>>>>>
>>>>>       public JAXBContext getContext(Class<?>    type) {
>>>>>                    try {
>>>>>                         jc = JAXBContextFactory.****createContext(new
>>>>>
>>>>> Class[]
>>>>> {MyObjectFactory.class}, null);
>>>>>
>>>>>                        return jc;
>>>>>                    } catch (JAXBException e) {
>>>>>                        e.printStackTrace();
>>>>>                    }
>>>>>                    return null;
>>>>>                }
>>>>>
>>>>> }
>>>>>
>>>>> Here is my ObjectFactory class:
>>>>> ------------------------------****-----------
>>>>>
>>>>> @XmlRegistry
>>>>> public class MyObjectFactory {
>>>>>
>>>>>
>>>>>       public Customer createCustomer() {
>>>>>          return createInstance(Customer.class)****;
>>>>>
>>>>>
>>>>>       }
>>>>>       ...
>>>>>
>>>>>
>>>>>       private<T>   T createInstance(Class<T>   anInterface)
{
>>>>>           return (T) Proxy.newProxyInstance(****
>>>>> anInterface.getClassLoader(),
>>>>>
>>>>> new
>>>>> Class[] {anInterface}, new InterfaceInvocationHandler());
>>>>>       }
>>>>>
>>>>>      private static class InterfaceInvocationHandler implements
>>>>> InvocationHandler {
>>>>>
>>>>>           private Map<String, Object>   values = new HashMap<String,
>>>>> Object>();
>>>>>
>>>>>           public Object invoke(Object proxy, Method method, Object[]
>>>>> args)
>>>>> throws Throwable {
>>>>>               String methodName = method.getName();
>>>>>               if(methodName.startsWith("get"****)) {
>>>>>                   return values.get(methodName.****substring(3));
>>>>>
>>>>>               }
>>>>>               else {
>>>>>                  values.put(methodName.****substring(3), args[0]);
>>>>>
>>>>>                   return null;
>>>>>               }
>>>>>           }
>>>>>
>>>>>       }
>>>>> }
>>>>>
>>>>> Here is my bean.xml file:
>>>>> ------------------------------****-----
>>>>>
>>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>>> <beans xmlns="http://www.**springfram**ework.org/schema/**beans<http://springframework.org/schema/**beans>
>>>>> <http:**//www.springframework.org/**schema/beans<http://www.springframework.org/schema/beans>
>>>>> >
>>>>> "
>>>>>          xmlns:xsi="http://www.w3.org/****2001/XMLSchema-instance<http://www.w3.org/**2001/XMLSchema-instance>
>>>>> <http:**//www.w3.org/2001/XMLSchema-**instance<http://www.w3.org/2001/XMLSchema-instance>
>>>>> >
>>>>> "
>>>>> xmlns:jaxrs="http://cxf.**apac**he.org/jaxrs <http://apache.org/jaxrs>
>>>>> <http://cxf.**apache.org/jaxrs <http://cxf.apache.org/jaxrs>>
>>>>> "
>>>>>          xsi:schemaLocation="
>>>>> http://www.springframework.****org/schema/beans<http://www.**
>>>>> springframework.org/schema/**beans<http://www.springframework.org/schema/beans>
>>>>> >
>>>>> http://www.springframework.****org/schema/beans/spring-beans.****xsd<
>>>>> http://www.**springframework.org/schema/**beans/spring-beans.xsd<http://www.springframework.org/schema/beans/spring-beans.xsd>
>>>>> >
>>>>> http://cxf.apache.org/jaxrs
>>>>> http://cxf.apache.org/schemas/****jaxrs.xsd<http://cxf.apache.org/schemas/**jaxrs.xsd>
>>>>> <http://cxf.apache.**org/schemas/jaxrs.xsd<http://cxf.apache.org/schemas/jaxrs.xsd>
>>>>> >
>>>>> ">
>>>>>          <import resource="classpath:META-INF/****cxf/cxf.xml" />
>>>>>         <import resource="classpath:META-INF/****cxf/cxf-servlet.xml"
>>>>> />
>>>>>
>>>>>          <jaxrs:server id="test" address="/">
>>>>>                  <jaxrs:serviceBeans>
>>>>>                          <ref bean="myWebService" />
>>>>>                  </jaxrs:serviceBeans>
>>>>>          <jaxrs:providers>
>>>>>                           <ref bean="MOXYProvider" />
>>>>>                 </jaxrs:providers>
>>>>>          </jaxrs:server>
>>>>>
>>>>>           <bean id="MOXYProvider" class="project.****MyContextResolver"
>>>>> />
>>>>>
>>>>>          <bean id="myWebService" class="project.Service" />
>>>>> </beans>
>>>>>
>>>>> Here is a the constructor of my service class:
>>>>> ------------------------------****----------------------
>>>>>
>>>>> public Service(){
>>>>>
>>>>>                  ObjectFactory objectFactory = new ObjectFactory();
>>>>>                  Customer c = objectFactory.createCustomer()****;
>>>>>
>>>>>                  c.setName("defaultName");
>>>>>                  Address address = objectFactory.createAddress();
>>>>>                  address.setCity("****defaultAddress");
>>>>>                  address.setStreet("****defaultStreet");
>>>>>                  c.setAddress(address);
>>>>>
>>>>>                  this.resources.put(c.getName()****, s);
>>>>>
>>>>>
>>>>>          }
>>>>>
>>>>> and here is my GET method:
>>>>>
>>>>>          @GET
>>>>>          @Path("/resources/{name}/")
>>>>>          public Customer getCustomer(@PathParam("name") String name)
{
>>>>>                   return this.resources.get(name);
>>>>>          }
>>>>>
>>>>> When I call my service, I get the following error:
>>>>>
>>>>> Exception in thread "main" Status : 500
>>>>> Headers :
>>>>> Date : Wed, 20 Feb 2013 16:02:30 GMT
>>>>> Content-Length : 65
>>>>> Content-Type : text/plain
>>>>> Connection : close
>>>>> Server : Apache-Coyote/1.1
>>>>> Error message :
>>>>> No message body writer has been found for response class $Proxy5.
>>>>>
>>>>>          at
>>>>> org.apache.cxf.jaxrs.client.****ClientProxyImpl.checkResponse(****
>>>>> ClientProxyImpl.java:250)
>>>>>          at
>>>>> org.apache.cxf.jaxrs.client.****ClientProxyImpl.****handleResponse(**
>>>>> ClientProxyImpl.java:517)
>>>>>          at
>>>>> org.apache.cxf.jaxrs.client.****ClientProxyImpl.****
>>>>> doChainedInvocation(**
>>>>> ClientProxyImpl.java:487)
>>>>>          at
>>>>> org.apache.cxf.jaxrs.client.****ClientProxyImpl.invoke(**
>>>>>
>>>>> ClientProxyImpl.java:188)
>>>>>          at $Proxy18.getResource(Unknown Source)
>>>>>          at project.Client.main(Client.****java:35)
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Any idea about this error please?
>>>>>
>>>>> Regards,
>>>>>
>>>>> Diana
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> View this message in context: http://cxf.547215.n5.nabble.**
>>>>> com/How-to-configure-cxf-to-****use-MOXY-Jaxb-for-RESTful-****
>>>>> tp5723506.html<http://cxf.**547215.n5.nabble.com/How-to-**
>>>>> configure-cxf-to-use-MOXY-**Jaxb-for-RESTful-tp5723506.**html<http://cxf.547215.n5.nabble.com/How-to-configure-cxf-to-use-MOXY-Jaxb-for-RESTful-tp5723506.html>
>>>>> >
>>>>>
>>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>>
>>>> --
>>>> Sergey Beryozkin
>>>>
>>>> Talend Community Coders
>>>> http://coders.talend.com/
>>>>
>>>> Blog: http://sberyozkin.blogspot.com
>>>>
>>>>
>>>
>>>
>>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message