You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Tom Hartwell <to...@gmail.com> on 2013/07/30 01:30:00 UTC

CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

I'm using CXF 2.6.6 and have not found an open issue regarding the problem
I'm seeing so I'm thinking it may be misconfiguration on my part.

I'm trying to use a CXF client in my application where I have my app wired
via Spring in XML:

test-context.xml

<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-2.0.xsd
         http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
">


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property />
        .....
    </bean>

    <bean id="myService" class="com.MyService">
        <property name="dataSource" ref="dataSource" />
        <property name="queries">
            <map>
                <entry key="SAVE">
                    <value>INSERT INTO ....</value>
                </entry>
                <entry key="UPDATE">
                    <value>UPDATE ...</value>
                </entry>
                <entry key="GET">
                    <value>SELECT ...</value>
                </entry>
                <entry key="DELETE">
                    <value>DELETE from ...</value>
                </entry>
            </map>
        </property>
    </bean>

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <bean id="jacksonMapper"
class="com.fasterxml.jackson.databind.ObjectMapper" />

    <jaxrs:server id="myServer" address="local://localservice/">
        <jaxrs:serviceBeans>
            <ref bean="myService" />
        </jaxrs:serviceBeans>
        <jaxrs:providers>
            <bean
class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
                <property name="mapper" ref="jacksonMapper" />
            </bean>
        </jaxrs:providers>
    </jaxrs:server>


    <jaxrs:client id="myClient" address="local://localservice/"
        serviceClass="com.MyServiceInterface"
        inheritHeaders="true">
        <jaxrs:headers>
            <entry key="Accept" value="application/json" />
            <entry key="ContentType" value="application/json" />
        </jaxrs:headers>
        <jaxrs:providers>
            <bean
class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider">
                <property name="mapper" ref="jacksonMapper" />
            </bean>
        </jaxrs:providers>
    </jaxrs:client>
</beans>

And my Jax-RS interface is as follows:

@Path("/")
public interface MyServiceInterface {

    @GET
    @Path("/{id}")
    @Produces("application/json")
    MyObject retreiveMyObject(@PathParam("id") int id);

    @POST
    @Path("/")
    @Consumes("application/json")
    @Produces("application/json")
    Integer saveMyObject(MyObject myObject);

    @PUT
    @Path("/{id}")
    @Consumes("application/json")
    @Produces("application/json")
    Integer updateMyObject(@PathParam("id") int id, MyObject myObject);

    @DELETE
    @Path("/{id}")
    @Produces("application/json")
    Integer deleteMyObject(@PathParam("id") int id);
}

public class MyService implements MyServiceInterface {
...
}

And the test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"test-context.xml"})
public class MyServiceTest extends Assert implements
ApplicationContextAware {

    private final Logger logger = LoggerFactory.getLogger(MyServiceTest
.class);

    ApplicationContext ctx;
    @Override
    public void setApplicationContext(ApplicationContext context) throws
BeansException {
        this.ctx = context;
    }

    @Autowired
    @Qualifier("myClient")
    public MyServiceInterface myServiceInterface;

    @Test
    public void testCrud() {
        MyObject myObject = new
MyObject().setAttr1("127.0.0.1").setAttr2(new Date());

        // THIS WORKS THROUGH THE CLIENT
        myObject.setId(myServiceInterface.saveMyObject(myObject));

        // THIS WORKS THROUGH THE CLIENT TOO
        myServiceInterface.updateMyObject(myObject.getId(), myObject
.setX(1.23f).setY(4.56f));

        // THIS DOES NOT HANG!!
        ((MyServiceInterface)ctx.getBean("myService")).deleteMyObject(1);


        // THIS HANGS
        logger.debug("BEGIN THE RETRIEVAL");
        MyObject persistedMyObject = myServiceInterface.retrieveMyObject(
myObject.getId());
        assertEquals(1.23f, persistedMyObject.getX(), 0.05);
        assertEquals(4.56f, persistedMyObject.getY(), 0.05);

        // THIS HANGS TOO??
        myServiceInterface.deleteMyObject(roomAlarm.getId());
        MyObject deletedMyObject = myServiceInterface.retrieveMyObject(
persistedMyObject.getId());

        assertNull(deletedMyObject);
    }
}

The log reads:
1728 [main] DEBUG com.MyObjectTest  - *BEGIN THE RETRIEVAL*
1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
interceptor org.apache.cxf.ws.policy.PolicyOutInterceptor@55e29b99 to phase
setup
1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
interceptor org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc to
phase prepare-send
1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
interceptor org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc to
phase prepare-send
1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Chain
org.apache.cxf.phase.PhaseInterceptorChain@7691a4fb was created. Current
flow:
  setup [PolicyOutInterceptor]
  prepare-send [MessageSenderInterceptor]

1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
handleMessage on interceptor
org.apache.cxf.ws.policy.PolicyOutInterceptor@55e29b99
1729 [main] DEBUG org.apache.cxf.ws.policy.PolicyOutInterceptor  - No
binding operation info.
1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
handleMessage on interceptor
org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc
1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
interceptor
org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@68d36ff3to
phase prepare-send-ending
1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Chain
org.apache.cxf.phase.PhaseInterceptorChain@7691a4fb was modified. Current
flow:
  setup [PolicyOutInterceptor]
  prepare-send [MessageSenderInterceptor]
  prepare-send-ending [MessageSenderEndingInterceptor]

1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
handleMessage on interceptor
org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@68d36ff3

The save and update work just fine, and the retrieve and delete don't. If I
call the service class directly I can retrieve and delete just fine, so I
have a feeling it has to do with my configuration, but I've tried a ton of
different things to no avail.

Thanks in advance,
Tom

Re: CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

Posted by Sergey Beryozkin <sb...@gmail.com>.
On 30/07/13 17:01, Sergey Beryozkin wrote:
> On 30/07/13 16:51, Tom Hartwell wrote:
>> Thanks so much Sergey, that did the trick. While I'm happy that my test
>> now works, I feel like this violates the Principle of Least Surprise in
>> setting up a Client in this way. Is there any compelling reason to not
>> set this property normally?
> Hmm, good point. Local transport module has been created long before we
> started supporting RS communications and with WS a request payload is
> available in most cases so I guess I worked just fine with the
> piped-style approach.
> I'll start a dev thread, seems like using a direct dispatch style by
> default can simplify things a bit so I'll update the code unless there
> are known reasons for not doing it

FYI, Dan has fixed it such that requests with empty payloads will work 
with or without this property being set up.

Cheers, Sergey

>
>>
>> Thanks again for identifying my problem!
>>
>> -Tom
>>
>>
>> On Tue, Jul 30, 2013 at 3:40 AM, Sergey Beryozkin <sberyozkin@gmail.com
>> <ma...@gmail.com>> wrote:
>>
>>     Actually the wiki mentions that property so I won't update it.
>>     But, at the moment, you can't set that property in jaxrs:client
>>     because LocalConduit does not check for message contextual
>>     properties, I've just got it fixed but in meantime please set the
>>     property from the code
>>
>>     Cheers, Sergey
>>
>>     On 30/07/13 10:52, Sergey Beryozkin wrote:
>>
>>         Hi
>>
>>         I've spotted you use a local transport. Yes, it is a test setup
>>         issue.
>>         Specifically, you use 'piped' local transport which as far as I
>>         recall
>>         assumes a payload is available and in case of GET/DELETE it is
>>         not so
>>         you have the code hanging.
>>         Add this property to your proxy (in
>>         jaxrs:client/jaxrs:properties)__:
>>         "org.apache.cxf.transport.__local.LocalConduit.__directDispatch"
>>         : true
>>
>>         I can see that LocalTransport handler uses Boolean.TRUE to
>>         compare, so
>>         that property value needs to be a proper boolean.
>>         Will do a minor update so that users can use String "true"...
>>
>>         Or you can set that property directly from the code,
>>
>>
>> WebClient.getConfig(__myServiceInterface).__getRequestContext().put(__LocalConduit.DIRECT_DISPATCH,
>>
>>         Boolean.TRUE);
>>
>>         I'll update the docs re the need to use this property with
>> requests
>>         having no payloads when Local transport is used.
>>
>>         Cheers, Sergey
>>
>>         On 30/07/13 00:30, Tom Hartwell wrote:
>>
>>             I'm using CXF 2.6.6 and have not found an open issue
>>             regarding the
>>             problem
>>             I'm seeing so I'm thinking it may be misconfiguration on my
>>             part.
>>
>>             I'm trying to use a CXF client in my application where I
>>             have my app
>>             wired
>>             via Spring in XML:
>>
>>             test-context.xml
>>
>>             <beans
>>             xmlns="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>" xmlns: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/spring-beans-__2.0.xsd
>>
>> <http://www.springframework.org/schema/beans/spring-beans-2.0.xsd>
>>             http://cxf.apache.org/jaxrs
>>             http://cxf.apache.org/schemas/__jaxrs.xsd
>>             <http://cxf.apache.org/schemas/jaxrs.xsd>
>>             ">
>>
>>
>>                   <bean id="dataSource"
>>             class="org.apache.commons.__dbcp.BasicDataSource"
>>                       destroy-method="close">
>>                       <property />
>>                       .....
>>                   </bean>
>>
>>                   <bean id="myService" class="com.MyService">
>>                       <property name="dataSource" ref="dataSource" />
>>                       <property name="queries">
>>                           <map>
>>                               <entry key="SAVE">
>>                                   <value>INSERT INTO ....</value>
>>                               </entry>
>>                               <entry key="UPDATE">
>>                                   <value>UPDATE ...</value>
>>                               </entry>
>>                               <entry key="GET">
>>                                   <value>SELECT ...</value>
>>                               </entry>
>>                               <entry key="DELETE">
>>                                   <value>DELETE from ...</value>
>>                               </entry>
>>                           </map>
>>                       </property>
>>                   </bean>
>>
>>                   <import resource="classpath:META-INF/__cxf/cxf.xml" />
>>                   <import
>>             resource="classpath:META-INF/__cxf/cxf-servlet.xml" />
>>
>>                   <bean id="jacksonMapper"
>>             class="com.fasterxml.jackson.__databind.ObjectMapper" />
>>
>>                   <jaxrs:server id="myServer"
>>             address="local://localservice/__">
>>                       <jaxrs:serviceBeans>
>>                           <ref bean="myService" />
>>                       </jaxrs:serviceBeans>
>>                       <jaxrs:providers>
>>                           <bean
>>
>> class="com.fasterxml.jackson.__jaxrs.json.__JacksonJsonProvider">
>>                               <property name="mapper"
>> ref="jacksonMapper" />
>>                           </bean>
>>                       </jaxrs:providers>
>>                   </jaxrs:server>
>>
>>
>>                   <jaxrs:client id="myClient"
>>             address="local://localservice/__"
>>                       serviceClass="com.__MyServiceInterface"
>>                       inheritHeaders="true">
>>                       <jaxrs:headers>
>>                           <entry key="Accept" value="application/json" />
>>                           <entry key="ContentType"
>>             value="application/json" />
>>                       </jaxrs:headers>
>>                       <jaxrs:providers>
>>                           <bean
>>
>> class="com.fasterxml.jackson.__jaxrs.json.__JacksonJaxbJsonProvider">
>>                               <property name="mapper"
>> ref="jacksonMapper" />
>>                           </bean>
>>                       </jaxrs:providers>
>>                   </jaxrs:client>
>>             </beans>
>>
>>             And my Jax-RS interface is as follows:
>>
>>             @Path("/")
>>             public interface MyServiceInterface {
>>
>>                   @GET
>>                   @Path("/{id}")
>>                   @Produces("application/json")
>>                   MyObject retreiveMyObject(@PathParam("__id") int id);
>>
>>                   @POST
>>                   @Path("/")
>>                   @Consumes("application/json")
>>                   @Produces("application/json")
>>                   Integer saveMyObject(MyObject myObject);
>>
>>                   @PUT
>>                   @Path("/{id}")
>>                   @Consumes("application/json")
>>                   @Produces("application/json")
>>                   Integer updateMyObject(@PathParam("id"__) int id,
>>             MyObject myObject);
>>
>>                   @DELETE
>>                   @Path("/{id}")
>>                   @Produces("application/json")
>>                   Integer deleteMyObject(@PathParam("id"__) int id);
>>             }
>>
>>             public class MyService implements MyServiceInterface {
>>             ...
>>             }
>>
>>             And the test
>>
>>             @RunWith(__SpringJUnit4ClassRunner.class)
>>             @ContextConfiguration(__locations={"test-context.xml"}__)
>>             public class MyServiceTest extends Assert implements
>>             ApplicationContextAware {
>>
>>                   private final Logger logger =
>>             LoggerFactory.getLogger(__MyServiceTest
>>             .class);
>>
>>                   ApplicationContext ctx;
>>                   @Override
>>                   public void setApplicationContext(__ApplicationContext
>>             context) throws
>>             BeansException {
>>                       this.ctx = context;
>>                   }
>>
>>                   @Autowired
>>                   @Qualifier("myClient")
>>                   public MyServiceInterface myServiceInterface;
>>
>>                   @Test
>>                   public void testCrud() {
>>                       MyObject myObject = new
>>             MyObject().setAttr1("127.0.0.__1").setAttr2(new Date());
>>
>>                       // THIS WORKS THROUGH THE CLIENT
>>
>>
>> myObject.setId(__myServiceInterface.__saveMyObject(myObject));
>>
>>                       // THIS WORKS THROUGH THE CLIENT TOO
>>
>>               myServiceInterface.__updateMyObject(myObject.getId(__),
>>             myObject
>>             .setX(1.23f).setY(4.56f));
>>
>>                       // THIS DOES NOT HANG!!
>>
>>
>> ((MyServiceInterface)ctx.__getBean("myService")).__deleteMyObject(1);
>>
>>
>>                       // THIS HANGS
>>                       logger.debug("BEGIN THE RETRIEVAL");
>>                       MyObject persistedMyObject =
>>             myServiceInterface.__retrieveMyObject(
>>             myObject.getId());
>>                       assertEquals(1.23f, persistedMyObject.getX(),
>> 0.05);
>>                       assertEquals(4.56f, persistedMyObject.getY(),
>> 0.05);
>>
>>                       // THIS HANGS TOO??
>>
>>               myServiceInterface.__deleteMyObject(roomAlarm.__getId());
>>                       MyObject deletedMyObject =
>>             myServiceInterface.__retrieveMyObject(
>>             persistedMyObject.getId());
>>
>>                       assertNull(deletedMyObject);
>>                   }
>>             }
>>
>>             The log reads:
>>             1728 [main] DEBUG com.MyObjectTest  - *BEGIN THE RETRIEVAL*
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>             org.apache.cxf.ws.policy.__PolicyOutInterceptor@55e29b99 to
>>             phase
>>             setup
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>>             to
>>             phase prepare-send
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>>             to
>>             phase prepare-send
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Chain
>>             org.apache.cxf.phase.__PhaseInterceptorChain@7691a4fb was
>>             created. Current
>>             flow:
>>                 setup [PolicyOutInterceptor]
>>                 prepare-send [MessageSenderInterceptor]
>>
>>             1728 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>>             handleMessage on interceptor
>>             org.apache.cxf.ws.policy.__PolicyOutInterceptor@55e29b99
>>             1729 [main] DEBUG
>>             org.apache.cxf.ws.policy.__PolicyOutInterceptor  - No
>>             binding operation info.
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>>             handleMessage on interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>>             interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor$__MessageSenderEndingInterceptor__@68d36ff3to
>>
>>
>>             phase prepare-send-ending
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Chain
>>             org.apache.cxf.phase.__PhaseInterceptorChain@7691a4fb was
>>             modified. Current
>>             flow:
>>                 setup [PolicyOutInterceptor]
>>                 prepare-send [MessageSenderInterceptor]
>>                 prepare-send-ending [__MessageSenderEndingInterceptor__]
>>
>>             1729 [main] DEBUG
>>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>>             handleMessage on interceptor
>>
>> org.apache.cxf.interceptor.__MessageSenderInterceptor$__MessageSenderEndingInterceptor__@68d36ff3
>>
>>
>>
>>             The save and update work just fine, and the retrieve and
>>             delete don't.
>>             If I
>>             call the service class directly I can retrieve and delete
>>             just fine, so I
>>             have a feeling it has to do with my configuration, but I've
>>             tried a
>>             ton of
>>             different things to no avail.
>>
>>             Thanks in advance,
>>             Tom
>>
>>
>>
>>
>>
>>     --
>>     Sergey Beryozkin
>>
>>     Talend Community Coders
>>     http://coders.talend.com/
>>
>>     Blog: http://sberyozkin.blogspot.com
>>
>>
>


Re: CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

Posted by Tom Hartwell <to...@gmail.com>.
Great, sounds good, thanks, Sergey.

-Tom

Re: CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

Posted by Sergey Beryozkin <sb...@gmail.com>.
On 30/07/13 16:51, Tom Hartwell wrote:
> Thanks so much Sergey, that did the trick. While I'm happy that my test
> now works, I feel like this violates the Principle of Least Surprise in
> setting up a Client in this way. Is there any compelling reason to not
> set this property normally?
Hmm, good point. Local transport module has been created long before we 
started supporting RS communications and with WS a request payload is 
available in most cases so I guess I worked just fine with the 
piped-style approach.
I'll start a dev thread, seems like using a direct dispatch style by 
default can simplify things a bit so I'll update the code unless there 
are known reasons for not doing it

Cheers, Sergey

>
> Thanks again for identifying my problem!
>
> -Tom
>
>
> On Tue, Jul 30, 2013 at 3:40 AM, Sergey Beryozkin <sberyozkin@gmail.com
> <ma...@gmail.com>> wrote:
>
>     Actually the wiki mentions that property so I won't update it.
>     But, at the moment, you can't set that property in jaxrs:client
>     because LocalConduit does not check for message contextual
>     properties, I've just got it fixed but in meantime please set the
>     property from the code
>
>     Cheers, Sergey
>
>     On 30/07/13 10:52, Sergey Beryozkin wrote:
>
>         Hi
>
>         I've spotted you use a local transport. Yes, it is a test setup
>         issue.
>         Specifically, you use 'piped' local transport which as far as I
>         recall
>         assumes a payload is available and in case of GET/DELETE it is
>         not so
>         you have the code hanging.
>         Add this property to your proxy (in
>         jaxrs:client/jaxrs:properties)__:
>         "org.apache.cxf.transport.__local.LocalConduit.__directDispatch"
>         : true
>
>         I can see that LocalTransport handler uses Boolean.TRUE to
>         compare, so
>         that property value needs to be a proper boolean.
>         Will do a minor update so that users can use String "true"...
>
>         Or you can set that property directly from the code,
>
>         WebClient.getConfig(__myServiceInterface).__getRequestContext().put(__LocalConduit.DIRECT_DISPATCH,
>         Boolean.TRUE);
>
>         I'll update the docs re the need to use this property with requests
>         having no payloads when Local transport is used.
>
>         Cheers, Sergey
>
>         On 30/07/13 00:30, Tom Hartwell wrote:
>
>             I'm using CXF 2.6.6 and have not found an open issue
>             regarding the
>             problem
>             I'm seeing so I'm thinking it may be misconfiguration on my
>             part.
>
>             I'm trying to use a CXF client in my application where I
>             have my app
>             wired
>             via Spring in XML:
>
>             test-context.xml
>
>             <beans
>             xmlns="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>" xmlns: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/spring-beans-__2.0.xsd
>             <http://www.springframework.org/schema/beans/spring-beans-2.0.xsd>
>             http://cxf.apache.org/jaxrs
>             http://cxf.apache.org/schemas/__jaxrs.xsd
>             <http://cxf.apache.org/schemas/jaxrs.xsd>
>             ">
>
>
>                   <bean id="dataSource"
>             class="org.apache.commons.__dbcp.BasicDataSource"
>                       destroy-method="close">
>                       <property />
>                       .....
>                   </bean>
>
>                   <bean id="myService" class="com.MyService">
>                       <property name="dataSource" ref="dataSource" />
>                       <property name="queries">
>                           <map>
>                               <entry key="SAVE">
>                                   <value>INSERT INTO ....</value>
>                               </entry>
>                               <entry key="UPDATE">
>                                   <value>UPDATE ...</value>
>                               </entry>
>                               <entry key="GET">
>                                   <value>SELECT ...</value>
>                               </entry>
>                               <entry key="DELETE">
>                                   <value>DELETE from ...</value>
>                               </entry>
>                           </map>
>                       </property>
>                   </bean>
>
>                   <import resource="classpath:META-INF/__cxf/cxf.xml" />
>                   <import
>             resource="classpath:META-INF/__cxf/cxf-servlet.xml" />
>
>                   <bean id="jacksonMapper"
>             class="com.fasterxml.jackson.__databind.ObjectMapper" />
>
>                   <jaxrs:server id="myServer"
>             address="local://localservice/__">
>                       <jaxrs:serviceBeans>
>                           <ref bean="myService" />
>                       </jaxrs:serviceBeans>
>                       <jaxrs:providers>
>                           <bean
>             class="com.fasterxml.jackson.__jaxrs.json.__JacksonJsonProvider">
>                               <property name="mapper" ref="jacksonMapper" />
>                           </bean>
>                       </jaxrs:providers>
>                   </jaxrs:server>
>
>
>                   <jaxrs:client id="myClient"
>             address="local://localservice/__"
>                       serviceClass="com.__MyServiceInterface"
>                       inheritHeaders="true">
>                       <jaxrs:headers>
>                           <entry key="Accept" value="application/json" />
>                           <entry key="ContentType"
>             value="application/json" />
>                       </jaxrs:headers>
>                       <jaxrs:providers>
>                           <bean
>             class="com.fasterxml.jackson.__jaxrs.json.__JacksonJaxbJsonProvider">
>                               <property name="mapper" ref="jacksonMapper" />
>                           </bean>
>                       </jaxrs:providers>
>                   </jaxrs:client>
>             </beans>
>
>             And my Jax-RS interface is as follows:
>
>             @Path("/")
>             public interface MyServiceInterface {
>
>                   @GET
>                   @Path("/{id}")
>                   @Produces("application/json")
>                   MyObject retreiveMyObject(@PathParam("__id") int id);
>
>                   @POST
>                   @Path("/")
>                   @Consumes("application/json")
>                   @Produces("application/json")
>                   Integer saveMyObject(MyObject myObject);
>
>                   @PUT
>                   @Path("/{id}")
>                   @Consumes("application/json")
>                   @Produces("application/json")
>                   Integer updateMyObject(@PathParam("id"__) int id,
>             MyObject myObject);
>
>                   @DELETE
>                   @Path("/{id}")
>                   @Produces("application/json")
>                   Integer deleteMyObject(@PathParam("id"__) int id);
>             }
>
>             public class MyService implements MyServiceInterface {
>             ...
>             }
>
>             And the test
>
>             @RunWith(__SpringJUnit4ClassRunner.class)
>             @ContextConfiguration(__locations={"test-context.xml"}__)
>             public class MyServiceTest extends Assert implements
>             ApplicationContextAware {
>
>                   private final Logger logger =
>             LoggerFactory.getLogger(__MyServiceTest
>             .class);
>
>                   ApplicationContext ctx;
>                   @Override
>                   public void setApplicationContext(__ApplicationContext
>             context) throws
>             BeansException {
>                       this.ctx = context;
>                   }
>
>                   @Autowired
>                   @Qualifier("myClient")
>                   public MyServiceInterface myServiceInterface;
>
>                   @Test
>                   public void testCrud() {
>                       MyObject myObject = new
>             MyObject().setAttr1("127.0.0.__1").setAttr2(new Date());
>
>                       // THIS WORKS THROUGH THE CLIENT
>
>               myObject.setId(__myServiceInterface.__saveMyObject(myObject));
>
>                       // THIS WORKS THROUGH THE CLIENT TOO
>
>               myServiceInterface.__updateMyObject(myObject.getId(__),
>             myObject
>             .setX(1.23f).setY(4.56f));
>
>                       // THIS DOES NOT HANG!!
>
>             ((MyServiceInterface)ctx.__getBean("myService")).__deleteMyObject(1);
>
>
>                       // THIS HANGS
>                       logger.debug("BEGIN THE RETRIEVAL");
>                       MyObject persistedMyObject =
>             myServiceInterface.__retrieveMyObject(
>             myObject.getId());
>                       assertEquals(1.23f, persistedMyObject.getX(), 0.05);
>                       assertEquals(4.56f, persistedMyObject.getY(), 0.05);
>
>                       // THIS HANGS TOO??
>
>               myServiceInterface.__deleteMyObject(roomAlarm.__getId());
>                       MyObject deletedMyObject =
>             myServiceInterface.__retrieveMyObject(
>             persistedMyObject.getId());
>
>                       assertNull(deletedMyObject);
>                   }
>             }
>
>             The log reads:
>             1728 [main] DEBUG com.MyObjectTest  - *BEGIN THE RETRIEVAL*
>             1728 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>             interceptor
>             org.apache.cxf.ws.policy.__PolicyOutInterceptor@55e29b99 to
>             phase
>             setup
>             1728 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>             interceptor
>             org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>             to
>             phase prepare-send
>             1728 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>             interceptor
>             org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>             to
>             phase prepare-send
>             1728 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Chain
>             org.apache.cxf.phase.__PhaseInterceptorChain@7691a4fb was
>             created. Current
>             flow:
>                 setup [PolicyOutInterceptor]
>                 prepare-send [MessageSenderInterceptor]
>
>             1728 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>             handleMessage on interceptor
>             org.apache.cxf.ws.policy.__PolicyOutInterceptor@55e29b99
>             1729 [main] DEBUG
>             org.apache.cxf.ws.policy.__PolicyOutInterceptor  - No
>             binding operation info.
>             1729 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>             handleMessage on interceptor
>             org.apache.cxf.interceptor.__MessageSenderInterceptor@__105585dc
>             1729 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Adding
>             interceptor
>             org.apache.cxf.interceptor.__MessageSenderInterceptor$__MessageSenderEndingInterceptor__@68d36ff3to
>
>             phase prepare-send-ending
>             1729 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Chain
>             org.apache.cxf.phase.__PhaseInterceptorChain@7691a4fb was
>             modified. Current
>             flow:
>                 setup [PolicyOutInterceptor]
>                 prepare-send [MessageSenderInterceptor]
>                 prepare-send-ending [__MessageSenderEndingInterceptor__]
>
>             1729 [main] DEBUG
>             org.apache.cxf.phase.__PhaseInterceptorChain  - Invoking
>             handleMessage on interceptor
>             org.apache.cxf.interceptor.__MessageSenderInterceptor$__MessageSenderEndingInterceptor__@68d36ff3
>
>
>             The save and update work just fine, and the retrieve and
>             delete don't.
>             If I
>             call the service class directly I can retrieve and delete
>             just fine, so I
>             have a feeling it has to do with my configuration, but I've
>             tried a
>             ton of
>             different things to no avail.
>
>             Thanks in advance,
>             Tom
>
>
>
>
>
>     --
>     Sergey Beryozkin
>
>     Talend Community Coders
>     http://coders.talend.com/
>
>     Blog: http://sberyozkin.blogspot.com
>
>


Re: CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

Posted by Tom Hartwell <to...@gmail.com>.
Thanks so much Sergey, that did the trick. While I'm happy that my test now
works, I feel like this violates the Principle of Least Surprise in setting
up a Client in this way. Is there any compelling reason to not set this
property normally?

Thanks again for identifying my problem!

-Tom


On Tue, Jul 30, 2013 at 3:40 AM, Sergey Beryozkin <sb...@gmail.com>wrote:

> Actually the wiki mentions that property so I won't update it.
> But, at the moment, you can't set that property in jaxrs:client because
> LocalConduit does not check for message contextual properties, I've just
> got it fixed but in meantime please set the property from the code
>
> Cheers, Sergey
>
> On 30/07/13 10:52, Sergey Beryozkin wrote:
>
>> Hi
>>
>> I've spotted you use a local transport. Yes, it is a test setup issue.
>> Specifically, you use 'piped' local transport which as far as I recall
>> assumes a payload is available and in case of GET/DELETE it is not so
>> you have the code hanging.
>> Add this property to your proxy (in jaxrs:client/jaxrs:properties)**:
>> "org.apache.cxf.transport.**local.LocalConduit.**directDispatch" : true
>>
>> I can see that LocalTransport handler uses Boolean.TRUE to compare, so
>> that property value needs to be a proper boolean.
>> Will do a minor update so that users can use String "true"...
>>
>> Or you can set that property directly from the code,
>>
>> WebClient.getConfig(**myServiceInterface).**getRequestContext().put(**
>> LocalConduit.DIRECT_DISPATCH,
>> Boolean.TRUE);
>>
>> I'll update the docs re the need to use this property with requests
>> having no payloads when Local transport is used.
>>
>> Cheers, Sergey
>>
>> On 30/07/13 00:30, Tom Hartwell wrote:
>>
>>> I'm using CXF 2.6.6 and have not found an open issue regarding the
>>> problem
>>> I'm seeing so I'm thinking it may be misconfiguration on my part.
>>>
>>> I'm trying to use a CXF client in my application where I have my app
>>> wired
>>> via Spring in XML:
>>>
>>> test-context.xml
>>>
>>> <beans xmlns="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>"
>>> xmlns: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/spring-beans-**2.0.xsd<http://www.springframework.org/schema/beans/spring-beans-2.0.xsd>
>>>           http://cxf.apache.org/jaxrs
>>> http://cxf.apache.org/schemas/**jaxrs.xsd<http://cxf.apache.org/schemas/jaxrs.xsd>
>>> ">
>>>
>>>
>>>      <bean id="dataSource"
>>> class="org.apache.commons.**dbcp.BasicDataSource"
>>>          destroy-method="close">
>>>          <property />
>>>          .....
>>>      </bean>
>>>
>>>      <bean id="myService" class="com.MyService">
>>>          <property name="dataSource" ref="dataSource" />
>>>          <property name="queries">
>>>              <map>
>>>                  <entry key="SAVE">
>>>                      <value>INSERT INTO ....</value>
>>>                  </entry>
>>>                  <entry key="UPDATE">
>>>                      <value>UPDATE ...</value>
>>>                  </entry>
>>>                  <entry key="GET">
>>>                      <value>SELECT ...</value>
>>>                  </entry>
>>>                  <entry key="DELETE">
>>>                      <value>DELETE from ...</value>
>>>                  </entry>
>>>              </map>
>>>          </property>
>>>      </bean>
>>>
>>>      <import resource="classpath:META-INF/**cxf/cxf.xml" />
>>>      <import resource="classpath:META-INF/**cxf/cxf-servlet.xml" />
>>>
>>>      <bean id="jacksonMapper"
>>> class="com.fasterxml.jackson.**databind.ObjectMapper" />
>>>
>>>      <jaxrs:server id="myServer" address="local://localservice/**">
>>>          <jaxrs:serviceBeans>
>>>              <ref bean="myService" />
>>>          </jaxrs:serviceBeans>
>>>          <jaxrs:providers>
>>>              <bean
>>> class="com.fasterxml.jackson.**jaxrs.json.**JacksonJsonProvider">
>>>                  <property name="mapper" ref="jacksonMapper" />
>>>              </bean>
>>>          </jaxrs:providers>
>>>      </jaxrs:server>
>>>
>>>
>>>      <jaxrs:client id="myClient" address="local://localservice/**"
>>>          serviceClass="com.**MyServiceInterface"
>>>          inheritHeaders="true">
>>>          <jaxrs:headers>
>>>              <entry key="Accept" value="application/json" />
>>>              <entry key="ContentType" value="application/json" />
>>>          </jaxrs:headers>
>>>          <jaxrs:providers>
>>>              <bean
>>> class="com.fasterxml.jackson.**jaxrs.json.**JacksonJaxbJsonProvider">
>>>                  <property name="mapper" ref="jacksonMapper" />
>>>              </bean>
>>>          </jaxrs:providers>
>>>      </jaxrs:client>
>>> </beans>
>>>
>>> And my Jax-RS interface is as follows:
>>>
>>> @Path("/")
>>> public interface MyServiceInterface {
>>>
>>>      @GET
>>>      @Path("/{id}")
>>>      @Produces("application/json")
>>>      MyObject retreiveMyObject(@PathParam("**id") int id);
>>>
>>>      @POST
>>>      @Path("/")
>>>      @Consumes("application/json")
>>>      @Produces("application/json")
>>>      Integer saveMyObject(MyObject myObject);
>>>
>>>      @PUT
>>>      @Path("/{id}")
>>>      @Consumes("application/json")
>>>      @Produces("application/json")
>>>      Integer updateMyObject(@PathParam("id"**) int id, MyObject
>>> myObject);
>>>
>>>      @DELETE
>>>      @Path("/{id}")
>>>      @Produces("application/json")
>>>      Integer deleteMyObject(@PathParam("id"**) int id);
>>> }
>>>
>>> public class MyService implements MyServiceInterface {
>>> ...
>>> }
>>>
>>> And the test
>>>
>>> @RunWith(**SpringJUnit4ClassRunner.class)
>>> @ContextConfiguration(**locations={"test-context.xml"}**)
>>> public class MyServiceTest extends Assert implements
>>> ApplicationContextAware {
>>>
>>>      private final Logger logger = LoggerFactory.getLogger(**
>>> MyServiceTest
>>> .class);
>>>
>>>      ApplicationContext ctx;
>>>      @Override
>>>      public void setApplicationContext(**ApplicationContext context)
>>> throws
>>> BeansException {
>>>          this.ctx = context;
>>>      }
>>>
>>>      @Autowired
>>>      @Qualifier("myClient")
>>>      public MyServiceInterface myServiceInterface;
>>>
>>>      @Test
>>>      public void testCrud() {
>>>          MyObject myObject = new
>>> MyObject().setAttr1("127.0.0.**1").setAttr2(new Date());
>>>
>>>          // THIS WORKS THROUGH THE CLIENT
>>>          myObject.setId(**myServiceInterface.**saveMyObject(myObject));
>>>
>>>          // THIS WORKS THROUGH THE CLIENT TOO
>>>          myServiceInterface.**updateMyObject(myObject.getId(**),
>>> myObject
>>> .setX(1.23f).setY(4.56f));
>>>
>>>          // THIS DOES NOT HANG!!
>>>
>>> ((MyServiceInterface)ctx.**getBean("myService")).**deleteMyObject(1);
>>>
>>>
>>>          // THIS HANGS
>>>          logger.debug("BEGIN THE RETRIEVAL");
>>>          MyObject persistedMyObject =
>>> myServiceInterface.**retrieveMyObject(
>>> myObject.getId());
>>>          assertEquals(1.23f, persistedMyObject.getX(), 0.05);
>>>          assertEquals(4.56f, persistedMyObject.getY(), 0.05);
>>>
>>>          // THIS HANGS TOO??
>>>          myServiceInterface.**deleteMyObject(roomAlarm.**getId());
>>>          MyObject deletedMyObject = myServiceInterface.**
>>> retrieveMyObject(
>>> persistedMyObject.getId());
>>>
>>>          assertNull(deletedMyObject);
>>>      }
>>> }
>>>
>>> The log reads:
>>> 1728 [main] DEBUG com.MyObjectTest  - *BEGIN THE RETRIEVAL*
>>> 1728 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  - Adding
>>> interceptor org.apache.cxf.ws.policy.**PolicyOutInterceptor@55e29b99 to
>>> phase
>>> setup
>>> 1728 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  - Adding
>>> interceptor
>>> org.apache.cxf.interceptor.**MessageSenderInterceptor@**105585dc to
>>> phase prepare-send
>>> 1728 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  - Adding
>>> interceptor
>>> org.apache.cxf.interceptor.**MessageSenderInterceptor@**105585dc to
>>> phase prepare-send
>>> 1728 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  - Chain
>>> org.apache.cxf.phase.**PhaseInterceptorChain@7691a4fb was created.
>>> Current
>>> flow:
>>>    setup [PolicyOutInterceptor]
>>>    prepare-send [MessageSenderInterceptor]
>>>
>>> 1728 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  -
>>> Invoking
>>> handleMessage on interceptor
>>> org.apache.cxf.ws.policy.**PolicyOutInterceptor@55e29b99
>>> 1729 [main] DEBUG org.apache.cxf.ws.policy.**PolicyOutInterceptor  - No
>>> binding operation info.
>>> 1729 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  -
>>> Invoking
>>> handleMessage on interceptor
>>> org.apache.cxf.interceptor.**MessageSenderInterceptor@**105585dc
>>> 1729 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  - Adding
>>> interceptor
>>> org.apache.cxf.interceptor.**MessageSenderInterceptor$**
>>> MessageSenderEndingInterceptor**@68d36ff3to
>>>
>>> phase prepare-send-ending
>>> 1729 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  - Chain
>>> org.apache.cxf.phase.**PhaseInterceptorChain@7691a4fb was modified.
>>> Current
>>> flow:
>>>    setup [PolicyOutInterceptor]
>>>    prepare-send [MessageSenderInterceptor]
>>>    prepare-send-ending [**MessageSenderEndingInterceptor**]
>>>
>>> 1729 [main] DEBUG org.apache.cxf.phase.**PhaseInterceptorChain  -
>>> Invoking
>>> handleMessage on interceptor
>>> org.apache.cxf.interceptor.**MessageSenderInterceptor$**
>>> MessageSenderEndingInterceptor**@68d36ff3
>>>
>>>
>>> The save and update work just fine, and the retrieve and delete don't.
>>> If I
>>> call the service class directly I can retrieve and delete just fine, so I
>>> have a feeling it has to do with my configuration, but I've tried a
>>> ton of
>>> different things to no avail.
>>>
>>> Thanks in advance,
>>> Tom
>>>
>>>
>>
>>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com
>

Re: CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

Posted by Sergey Beryozkin <sb...@gmail.com>.
Actually the wiki mentions that property so I won't update it.
But, at the moment, you can't set that property in jaxrs:client because 
LocalConduit does not check for message contextual properties, I've just 
got it fixed but in meantime please set the property from the code

Cheers, Sergey
On 30/07/13 10:52, Sergey Beryozkin wrote:
> Hi
>
> I've spotted you use a local transport. Yes, it is a test setup issue.
> Specifically, you use 'piped' local transport which as far as I recall
> assumes a payload is available and in case of GET/DELETE it is not so
> you have the code hanging.
> Add this property to your proxy (in jaxrs:client/jaxrs:properties):
> "org.apache.cxf.transport.local.LocalConduit.directDispatch" : true
>
> I can see that LocalTransport handler uses Boolean.TRUE to compare, so
> that property value needs to be a proper boolean.
> Will do a minor update so that users can use String "true"...
>
> Or you can set that property directly from the code,
>
> WebClient.getConfig(myServiceInterface).getRequestContext().put(LocalConduit.DIRECT_DISPATCH,
> Boolean.TRUE);
>
> I'll update the docs re the need to use this property with requests
> having no payloads when Local transport is used.
>
> Cheers, Sergey
>
> On 30/07/13 00:30, Tom Hartwell wrote:
>> I'm using CXF 2.6.6 and have not found an open issue regarding the
>> problem
>> I'm seeing so I'm thinking it may be misconfiguration on my part.
>>
>> I'm trying to use a CXF client in my application where I have my app
>> wired
>> via Spring in XML:
>>
>> test-context.xml
>>
>> <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-2.0.xsd
>>           http://cxf.apache.org/jaxrs
>> http://cxf.apache.org/schemas/jaxrs.xsd
>> ">
>>
>>
>>      <bean id="dataSource"
>> class="org.apache.commons.dbcp.BasicDataSource"
>>          destroy-method="close">
>>          <property />
>>          .....
>>      </bean>
>>
>>      <bean id="myService" class="com.MyService">
>>          <property name="dataSource" ref="dataSource" />
>>          <property name="queries">
>>              <map>
>>                  <entry key="SAVE">
>>                      <value>INSERT INTO ....</value>
>>                  </entry>
>>                  <entry key="UPDATE">
>>                      <value>UPDATE ...</value>
>>                  </entry>
>>                  <entry key="GET">
>>                      <value>SELECT ...</value>
>>                  </entry>
>>                  <entry key="DELETE">
>>                      <value>DELETE from ...</value>
>>                  </entry>
>>              </map>
>>          </property>
>>      </bean>
>>
>>      <import resource="classpath:META-INF/cxf/cxf.xml" />
>>      <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
>>
>>      <bean id="jacksonMapper"
>> class="com.fasterxml.jackson.databind.ObjectMapper" />
>>
>>      <jaxrs:server id="myServer" address="local://localservice/">
>>          <jaxrs:serviceBeans>
>>              <ref bean="myService" />
>>          </jaxrs:serviceBeans>
>>          <jaxrs:providers>
>>              <bean
>> class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
>>                  <property name="mapper" ref="jacksonMapper" />
>>              </bean>
>>          </jaxrs:providers>
>>      </jaxrs:server>
>>
>>
>>      <jaxrs:client id="myClient" address="local://localservice/"
>>          serviceClass="com.MyServiceInterface"
>>          inheritHeaders="true">
>>          <jaxrs:headers>
>>              <entry key="Accept" value="application/json" />
>>              <entry key="ContentType" value="application/json" />
>>          </jaxrs:headers>
>>          <jaxrs:providers>
>>              <bean
>> class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider">
>>                  <property name="mapper" ref="jacksonMapper" />
>>              </bean>
>>          </jaxrs:providers>
>>      </jaxrs:client>
>> </beans>
>>
>> And my Jax-RS interface is as follows:
>>
>> @Path("/")
>> public interface MyServiceInterface {
>>
>>      @GET
>>      @Path("/{id}")
>>      @Produces("application/json")
>>      MyObject retreiveMyObject(@PathParam("id") int id);
>>
>>      @POST
>>      @Path("/")
>>      @Consumes("application/json")
>>      @Produces("application/json")
>>      Integer saveMyObject(MyObject myObject);
>>
>>      @PUT
>>      @Path("/{id}")
>>      @Consumes("application/json")
>>      @Produces("application/json")
>>      Integer updateMyObject(@PathParam("id") int id, MyObject myObject);
>>
>>      @DELETE
>>      @Path("/{id}")
>>      @Produces("application/json")
>>      Integer deleteMyObject(@PathParam("id") int id);
>> }
>>
>> public class MyService implements MyServiceInterface {
>> ...
>> }
>>
>> And the test
>>
>> @RunWith(SpringJUnit4ClassRunner.class)
>> @ContextConfiguration(locations={"test-context.xml"})
>> public class MyServiceTest extends Assert implements
>> ApplicationContextAware {
>>
>>      private final Logger logger = LoggerFactory.getLogger(MyServiceTest
>> .class);
>>
>>      ApplicationContext ctx;
>>      @Override
>>      public void setApplicationContext(ApplicationContext context) throws
>> BeansException {
>>          this.ctx = context;
>>      }
>>
>>      @Autowired
>>      @Qualifier("myClient")
>>      public MyServiceInterface myServiceInterface;
>>
>>      @Test
>>      public void testCrud() {
>>          MyObject myObject = new
>> MyObject().setAttr1("127.0.0.1").setAttr2(new Date());
>>
>>          // THIS WORKS THROUGH THE CLIENT
>>          myObject.setId(myServiceInterface.saveMyObject(myObject));
>>
>>          // THIS WORKS THROUGH THE CLIENT TOO
>>          myServiceInterface.updateMyObject(myObject.getId(), myObject
>> .setX(1.23f).setY(4.56f));
>>
>>          // THIS DOES NOT HANG!!
>>
>> ((MyServiceInterface)ctx.getBean("myService")).deleteMyObject(1);
>>
>>
>>          // THIS HANGS
>>          logger.debug("BEGIN THE RETRIEVAL");
>>          MyObject persistedMyObject =
>> myServiceInterface.retrieveMyObject(
>> myObject.getId());
>>          assertEquals(1.23f, persistedMyObject.getX(), 0.05);
>>          assertEquals(4.56f, persistedMyObject.getY(), 0.05);
>>
>>          // THIS HANGS TOO??
>>          myServiceInterface.deleteMyObject(roomAlarm.getId());
>>          MyObject deletedMyObject = myServiceInterface.retrieveMyObject(
>> persistedMyObject.getId());
>>
>>          assertNull(deletedMyObject);
>>      }
>> }
>>
>> The log reads:
>> 1728 [main] DEBUG com.MyObjectTest  - *BEGIN THE RETRIEVAL*
>> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
>> interceptor org.apache.cxf.ws.policy.PolicyOutInterceptor@55e29b99 to
>> phase
>> setup
>> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
>> interceptor
>> org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc to
>> phase prepare-send
>> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
>> interceptor
>> org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc to
>> phase prepare-send
>> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Chain
>> org.apache.cxf.phase.PhaseInterceptorChain@7691a4fb was created. Current
>> flow:
>>    setup [PolicyOutInterceptor]
>>    prepare-send [MessageSenderInterceptor]
>>
>> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
>> handleMessage on interceptor
>> org.apache.cxf.ws.policy.PolicyOutInterceptor@55e29b99
>> 1729 [main] DEBUG org.apache.cxf.ws.policy.PolicyOutInterceptor  - No
>> binding operation info.
>> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
>> handleMessage on interceptor
>> org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc
>> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
>> interceptor
>> org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@68d36ff3to
>>
>> phase prepare-send-ending
>> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Chain
>> org.apache.cxf.phase.PhaseInterceptorChain@7691a4fb was modified. Current
>> flow:
>>    setup [PolicyOutInterceptor]
>>    prepare-send [MessageSenderInterceptor]
>>    prepare-send-ending [MessageSenderEndingInterceptor]
>>
>> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
>> handleMessage on interceptor
>> org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@68d36ff3
>>
>>
>> The save and update work just fine, and the retrieve and delete don't.
>> If I
>> call the service class directly I can retrieve and delete just fine, so I
>> have a feeling it has to do with my configuration, but I've tried a
>> ton of
>> different things to no avail.
>>
>> Thanks in advance,
>> Tom
>>
>
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: CXF Jax-RS Client sends POST/PUT fine, GET/DELETE hang

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

I've spotted you use a local transport. Yes, it is a test setup issue.
Specifically, you use 'piped' local transport which as far as I recall 
assumes a payload is available and in case of GET/DELETE it is not so 
you have the code hanging.
Add this property to your proxy (in jaxrs:client/jaxrs:properties):
"org.apache.cxf.transport.local.LocalConduit.directDispatch" : true

I can see that LocalTransport handler uses Boolean.TRUE to compare, so 
that property value needs to be a proper boolean.
Will do a minor update so that users can use String "true"...

Or you can set that property directly from the code,

WebClient.getConfig(myServiceInterface).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, 
Boolean.TRUE);

I'll update the docs re the need to use this property with requests 
having no payloads when Local transport is used.

Cheers, Sergey

On 30/07/13 00:30, Tom Hartwell wrote:
> I'm using CXF 2.6.6 and have not found an open issue regarding the problem
> I'm seeing so I'm thinking it may be misconfiguration on my part.
>
> I'm trying to use a CXF client in my application where I have my app wired
> via Spring in XML:
>
> test-context.xml
>
> <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-2.0.xsd
>           http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
> ">
>
>
>      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
>          destroy-method="close">
>          <property />
>          .....
>      </bean>
>
>      <bean id="myService" class="com.MyService">
>          <property name="dataSource" ref="dataSource" />
>          <property name="queries">
>              <map>
>                  <entry key="SAVE">
>                      <value>INSERT INTO ....</value>
>                  </entry>
>                  <entry key="UPDATE">
>                      <value>UPDATE ...</value>
>                  </entry>
>                  <entry key="GET">
>                      <value>SELECT ...</value>
>                  </entry>
>                  <entry key="DELETE">
>                      <value>DELETE from ...</value>
>                  </entry>
>              </map>
>          </property>
>      </bean>
>
>      <import resource="classpath:META-INF/cxf/cxf.xml" />
>      <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
>
>      <bean id="jacksonMapper"
> class="com.fasterxml.jackson.databind.ObjectMapper" />
>
>      <jaxrs:server id="myServer" address="local://localservice/">
>          <jaxrs:serviceBeans>
>              <ref bean="myService" />
>          </jaxrs:serviceBeans>
>          <jaxrs:providers>
>              <bean
> class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
>                  <property name="mapper" ref="jacksonMapper" />
>              </bean>
>          </jaxrs:providers>
>      </jaxrs:server>
>
>
>      <jaxrs:client id="myClient" address="local://localservice/"
>          serviceClass="com.MyServiceInterface"
>          inheritHeaders="true">
>          <jaxrs:headers>
>              <entry key="Accept" value="application/json" />
>              <entry key="ContentType" value="application/json" />
>          </jaxrs:headers>
>          <jaxrs:providers>
>              <bean
> class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider">
>                  <property name="mapper" ref="jacksonMapper" />
>              </bean>
>          </jaxrs:providers>
>      </jaxrs:client>
> </beans>
>
> And my Jax-RS interface is as follows:
>
> @Path("/")
> public interface MyServiceInterface {
>
>      @GET
>      @Path("/{id}")
>      @Produces("application/json")
>      MyObject retreiveMyObject(@PathParam("id") int id);
>
>      @POST
>      @Path("/")
>      @Consumes("application/json")
>      @Produces("application/json")
>      Integer saveMyObject(MyObject myObject);
>
>      @PUT
>      @Path("/{id}")
>      @Consumes("application/json")
>      @Produces("application/json")
>      Integer updateMyObject(@PathParam("id") int id, MyObject myObject);
>
>      @DELETE
>      @Path("/{id}")
>      @Produces("application/json")
>      Integer deleteMyObject(@PathParam("id") int id);
> }
>
> public class MyService implements MyServiceInterface {
> ...
> }
>
> And the test
>
> @RunWith(SpringJUnit4ClassRunner.class)
> @ContextConfiguration(locations={"test-context.xml"})
> public class MyServiceTest extends Assert implements
> ApplicationContextAware {
>
>      private final Logger logger = LoggerFactory.getLogger(MyServiceTest
> .class);
>
>      ApplicationContext ctx;
>      @Override
>      public void setApplicationContext(ApplicationContext context) throws
> BeansException {
>          this.ctx = context;
>      }
>
>      @Autowired
>      @Qualifier("myClient")
>      public MyServiceInterface myServiceInterface;
>
>      @Test
>      public void testCrud() {
>          MyObject myObject = new
> MyObject().setAttr1("127.0.0.1").setAttr2(new Date());
>
>          // THIS WORKS THROUGH THE CLIENT
>          myObject.setId(myServiceInterface.saveMyObject(myObject));
>
>          // THIS WORKS THROUGH THE CLIENT TOO
>          myServiceInterface.updateMyObject(myObject.getId(), myObject
> .setX(1.23f).setY(4.56f));
>
>          // THIS DOES NOT HANG!!
>          ((MyServiceInterface)ctx.getBean("myService")).deleteMyObject(1);
>
>
>          // THIS HANGS
>          logger.debug("BEGIN THE RETRIEVAL");
>          MyObject persistedMyObject = myServiceInterface.retrieveMyObject(
> myObject.getId());
>          assertEquals(1.23f, persistedMyObject.getX(), 0.05);
>          assertEquals(4.56f, persistedMyObject.getY(), 0.05);
>
>          // THIS HANGS TOO??
>          myServiceInterface.deleteMyObject(roomAlarm.getId());
>          MyObject deletedMyObject = myServiceInterface.retrieveMyObject(
> persistedMyObject.getId());
>
>          assertNull(deletedMyObject);
>      }
> }
>
> The log reads:
> 1728 [main] DEBUG com.MyObjectTest  - *BEGIN THE RETRIEVAL*
> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
> interceptor org.apache.cxf.ws.policy.PolicyOutInterceptor@55e29b99 to phase
> setup
> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
> interceptor org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc to
> phase prepare-send
> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
> interceptor org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc to
> phase prepare-send
> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Chain
> org.apache.cxf.phase.PhaseInterceptorChain@7691a4fb was created. Current
> flow:
>    setup [PolicyOutInterceptor]
>    prepare-send [MessageSenderInterceptor]
>
> 1728 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
> handleMessage on interceptor
> org.apache.cxf.ws.policy.PolicyOutInterceptor@55e29b99
> 1729 [main] DEBUG org.apache.cxf.ws.policy.PolicyOutInterceptor  - No
> binding operation info.
> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
> handleMessage on interceptor
> org.apache.cxf.interceptor.MessageSenderInterceptor@105585dc
> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Adding
> interceptor
> org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@68d36ff3to
> phase prepare-send-ending
> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Chain
> org.apache.cxf.phase.PhaseInterceptorChain@7691a4fb was modified. Current
> flow:
>    setup [PolicyOutInterceptor]
>    prepare-send [MessageSenderInterceptor]
>    prepare-send-ending [MessageSenderEndingInterceptor]
>
> 1729 [main] DEBUG org.apache.cxf.phase.PhaseInterceptorChain  - Invoking
> handleMessage on interceptor
> org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor@68d36ff3
>
> The save and update work just fine, and the retrieve and delete don't. If I
> call the service class directly I can retrieve and delete just fine, so I
> have a feeling it has to do with my configuration, but I've tried a ton of
> different things to no avail.
>
> Thanks in advance,
> Tom
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com