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

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

I believe it is an old and known issue with overlapping Servlet Destinations, 
in fact there was a patch proposed awhile back on the users list. We'll need to 
resurrect it,

in mean time, what the following should fix it :

1. Have a single servlet mapping

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

2. Have multiple jaxrs endpoint definitions linking to the same service bean 
with unique address values :

<jaxrs:server id="myService" address="/one">
<jaxrs:serviceBeans>
<ref bean="serviceImpl" />
</jaxrs:serviceBeans>
</jaxrs:server>

<jaxrs:server id="myService" address="/two">
<jaxrs:serviceBeans>
<ref bean="serviceImpl" />
</jaxrs:serviceBeans>
</jaxrs:server>


This is nearly identical to your original setup, but instead we just push the 
support for multiple contexts down to the beans.xml

I'm nearly sure the same trick would have to be employed for jaxws services in 
a similar setup

let us know if it works for you.

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
>         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