[ 
https://issues.apache.org/jira/browse/CXF-2997?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12916493#action_12916493
 ] 

Sergey Beryozkin commented on CXF-2997:
---------------------------------------

Hi Ate

thanks a million.
Yes, we need to think it over, I suspect that the reason overwriting is done is 
that further down the chain (JAXWS) WebServiceContexts or WSA, etc, can deal 
with addresses in the transport independent manner, irrespectively of whether
it is HTTP or JMS, etc...

I'll create another JIRA so that we can track that
cheers, Sergey

> CXF JAX-RS not thread safe when accessing multiple destinations concurrently 
> -----------------------------------------------------------------------------
>
>                 Key: CXF-2997
>                 URL: https://issues.apache.org/jira/browse/CXF-2997
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS, Transports
>    Affects Versions: 2.2.10
>            Reporter: Ate Douma
>            Priority: Blocker
>             Fix For: 2.3, 2.2.11
>
>         Attachments: cxf-rest-test.tar.gz
>
>
> If a (single) JAX-RS service is invoked concurrently for different 
> destinations, the CXF ServletController and ServletTransportFactory 
> implementations override the current Destination state between these 
> invocations.
> I have created a simple test web application using Spring to expose this 
> problem.
> My example ServiceImpl.java looks like:
> @Path("/myservice/")
> @Produces("application/xml")
> public class ServiceImpl {
>   volatile boolean locked;
>   @GET
>   @Path("/uris")
>   @Produces("text/plain")
>   public String getUris(@Context UriInfo uriInfo) {
>     StringBuilder uris = new StringBuilder("BaseUri on entry: 
> "+uriInfo.getBaseUri().toString()).append("\n");
>     try {
>       while (locked) {
>         Thread.sleep(1000);
>       }
>     }  
>     catch (Exception x) {}
>     return uris.append("BaseUri on exit : " + 
> uriInfo.getBaseUri().toString()).append("\n").toString();
>   }
>     
>   @GET
>   @Path("/lock")
>   @Produces("text/plain")
>   public String lock() {
>     locked = true;
>     return "locked";
>   }
>   @GET
>   @Path("/unlock")
>   @Produces("text/plain")
>   public String unlock() {
>     locked = false;
>     return "unlocked";
>   }
> And in my web.xml I defined two CXFServlet mappings as follows:
>     <servlet-mapping>
>         <servlet-name>CXFServlet</servlet-name>
>         <url-pattern>/one/*</url-pattern>
>     </servlet-mapping>
>     <servlet-mapping>
>         <servlet-name>CXFServlet</servlet-name>
>         <url-pattern>/two/*</url-pattern>
>     </servlet-mapping>
> Finally, in Spring ApplicationContext.xml I setup the jaxrs server like this:
>     <jaxrs:server id="myService" address="/">
>         <jaxrs:serviceBeans>
>             <ref bean="serviceImpl" />
>         </jaxrs:serviceBeans>
>         <jaxrs:extensionMappings>
>             <entry key="xml" value="application/xml" />
>         </jaxrs:extensionMappings>
>     </jaxrs:server>
>     <bean id="serviceImpl" class="service.ServiceImpl" />
> As can be seen from the ServicesImpl.java, I used a trick to temporarily 
> "lock" and "unlock" a call to /myservice/uris from another request using 
> /myservice/lock and /myservice/unlock.
> Without locking, a call to http://localhost:8085/one/myservice/uris produces 
> the expected following result:
>   BaseUri on entry: http://localhost:8085/one/
>   BaseUri on exit : http://localhost:8085/two/
> However, if I first call http://localhost:8085/one/myservice/lock, then 
> http://localhost:8085/one/myservice/uris (blocked), and finally 
> http://127.0.0.1:8085/two/myservice/unlock (note the different hostname 
> 127.0.0.1 and servletPath /two) I get the following result:
>   BaseUri on entry: http://localhost:8085/one/
>   BaseUri on exit : http://127.0.0.1:8085/two/
> Clearly, UriInfo.getBaseURI() isn't thread safe as is shown above.
> After debugging a bit the current (CXF 2.2.10) implementation of the 
> ServletController and ServletTransportFactory, it looks like the 
> ServletController.updateDests(HttpServletRequest) method and the 
> ServletTransportFactory as a whole don't maintain resolved Destination state 
> isolated per request.
> Our CXF (JAX-RS) application exposes the same REST service to be called from 
> many different addresses (hosts) as well as upfront unknown servlet paths, 
> this really is a blocking issue.
> To be more concrete, we have to use a request wrapper to dynamically "mount" 
> the same rest service for different urls (its a front end for a unlimited 
> hierarchical resources repository). 
> Is there an easy way to protect JAX-RS service interactions from concurrent 
> invocations, e.g. by using special configurations, or is this indeed a 
> serious bug which will have to be fixed first? 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to