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 <[email protected]>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 >
