You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2013/05/01 17:42:53 UTC

svn commit: r1478057 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/blueprint/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ rt/frontend/jaxrs/src/main...

Author: sergeyb
Date: Wed May  1 15:42:52 2013
New Revision: 1478057

URL: http://svn.apache.org/r1478057
Log:
[CXF-4988] Support for instantiating providers with non default constructors

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/blueprint/BlueprintResourceFactory.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringResourceFactory.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerNonSpringBookTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/blueprint/BlueprintResourceFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/blueprint/BlueprintResourceFactory.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/blueprint/BlueprintResourceFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/blueprint/BlueprintResourceFactory.java Wed May  1 15:42:52 2013
@@ -70,7 +70,7 @@ public class BlueprintResourceFactory im
 
     public Object getInstance(Message m) {
         //TODO -- This is not the BP way.
-        Object[] values = ResourceUtils.createConstructorArguments(c, m);
+        Object[] values = ResourceUtils.createConstructorArguments(c, m, !isSingleton());
         //TODO Very springish...
         Object instance = values.length > 0 ? blueprintContainer.getComponentInstance(beanId) 
             : blueprintContainer.getComponentInstance(beanId);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/PerRequestResourceProvider.java Wed May  1 15:42:52 2013
@@ -66,7 +66,7 @@ public class PerRequestResourceProvider 
     
     protected Object createInstance(Message m) {
         
-        Object[] values = ResourceUtils.createConstructorArguments(c, m);
+        Object[] values = ResourceUtils.createConstructorArguments(c, m, true);
         try {
             Object instance = values.length > 0 ? c.newInstance(values) : c.newInstance(new Object[]{});
             InjectionUtils.invokeLifeCycleMethod(instance, postConstructMethod);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/AbstractResourceInfo.java Wed May  1 15:42:52 2013
@@ -42,6 +42,7 @@ import org.apache.cxf.jaxrs.utils.Inject
 public abstract class AbstractResourceInfo {
     private static final String FIELD_PROXY_MAP = "jaxrs-field-proxy-map";
     private static final String SETTER_PROXY_MAP = "jaxrs-setter-proxy-map";
+    private static final String CONSTRUCTOR_PROXY_MAP = "jaxrs-constructor-proxy-map";
     
     protected boolean root;
     protected Class<?> resourceClass;
@@ -50,6 +51,7 @@ public abstract class AbstractResourceIn
     private Map<Class<?>, List<Field>> contextFields;
     private Map<Class<?>, Map<Class<?>, Method>> contextMethods;
     private Bus bus;
+    private boolean constructorProxiesAvailable;
     private boolean contextsAvailable;
     
     protected AbstractResourceInfo(Bus bus) {
@@ -57,26 +59,38 @@ public abstract class AbstractResourceIn
     }
 
     protected AbstractResourceInfo(Class<?> resourceClass, Class<?> serviceClass, 
-                                   boolean isRoot, Bus bus) {
-        this(resourceClass, serviceClass, isRoot, true, bus);
+                                   boolean isRoot, boolean checkContexts, Bus bus) {
+        this(resourceClass, serviceClass, isRoot, checkContexts, null, bus);
     }
     
-    protected AbstractResourceInfo(Class<?> resourceClass, Class<?> serviceClass, 
-                                   boolean isRoot, boolean checkContexts, Bus bus) {
+    protected AbstractResourceInfo(Class<?> resourceClass, 
+                                   Class<?> serviceClass, 
+                                   boolean isRoot, 
+                                   boolean checkContexts,
+                                   Map<Class<?>, ThreadLocalProxy<?>> constructorProxies,
+                                   Bus bus) {
         this.bus = bus;
         this.serviceClass = serviceClass;
         this.resourceClass = resourceClass;
         root = isRoot;
         if (checkContexts && resourceClass != null) {
-            findContexts(serviceClass);   
+            findContexts(serviceClass, constructorProxies);
         }
     }
     
-    private void findContexts(Class<?> cls) {
+    private void findContexts(Class<?> cls, Map<Class<?>, ThreadLocalProxy<?>> constructorProxies) {
         findContextFields(cls);
         findContextSetterMethods(cls);
+        if (constructorProxies != null) {
+            Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>> proxies = getConstructorProxyMap(true);
+            proxies.put(serviceClass, constructorProxies);
+            constructorProxiesAvailable = true;
+        }
+        
+        
         contextsAvailable = contextFields != null && !contextFields.isEmpty() 
-            || contextMethods != null && !contextMethods.isEmpty();
+            || contextMethods != null && !contextMethods.isEmpty()
+            || constructorProxiesAvailable;
     }
     
     public boolean contextsAvailable() {
@@ -90,7 +104,7 @@ public abstract class AbstractResourceIn
     public void setResourceClass(Class<?> rClass) {
         resourceClass = rClass;
         if (serviceClass.isInterface() && resourceClass != null && !resourceClass.isInterface()) {
-            findContexts(resourceClass);
+            findContexts(resourceClass, null);
         }
     }
     
@@ -108,7 +122,7 @@ public abstract class AbstractResourceIn
                     && AnnotationUtils.isContextClass(f.getType())) {
                     contextFields = addContextField(contextFields, f);
                     if (f.getType() != Application.class) {
-                        addToMap(getFieldProxyMap(), f, InjectionUtils.createThreadLocalProxy(f.getType()));
+                        addToMap(getFieldProxyMap(true), f, InjectionUtils.createThreadLocalProxy(f.getType()));
                     }
                 }
             }
@@ -117,9 +131,9 @@ public abstract class AbstractResourceIn
     }
     
     @SuppressWarnings("unchecked")
-    private <T> Map<Class<?>, Map<T, ThreadLocalProxy<?>>> getProxyMap(Class<T> keyCls, String prop) {
+    private <T> Map<Class<?>, Map<T, ThreadLocalProxy<?>>> getProxyMap(Class<T> keyCls, String prop, boolean create) {
         Object property = bus.getProperty(prop);
-        if (property == null) {
+        if (property == null && create) {
             Map<Class<?>, Map<T, ThreadLocalProxy<?>>> map
                 = new ConcurrentHashMap<Class<?>, Map<T, ThreadLocalProxy<?>>>(2);
             bus.setProperty(prop, map);
@@ -128,12 +142,32 @@ public abstract class AbstractResourceIn
         return (Map<Class<?>, Map<T, ThreadLocalProxy<?>>>)property;
     }
     
-    private Map<Class<?>, Map<Field, ThreadLocalProxy<?>>> getFieldProxyMap() {
-        return getProxyMap(Field.class, FIELD_PROXY_MAP);
+    public Map<Class<?>, ThreadLocalProxy<?>> getConstructorProxies() {
+        if (constructorProxiesAvailable) {
+            return getConstructorProxyMap(false).get(serviceClass);
+        } else {
+            return null;
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>> getConstructorProxyMap(boolean create) {
+        Object property = bus.getProperty(CONSTRUCTOR_PROXY_MAP);
+        if (property == null) {
+            Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>> map
+                = new ConcurrentHashMap<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>>(2);
+            bus.setProperty(CONSTRUCTOR_PROXY_MAP, map);
+            property = map;
+        }
+        return (Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>>)property;
+    }
+    
+    private Map<Class<?>, Map<Field, ThreadLocalProxy<?>>> getFieldProxyMap(boolean create) {
+        return getProxyMap(Field.class, FIELD_PROXY_MAP, create);
     }
     
-    private Map<Class<?>, Map<Method, ThreadLocalProxy<?>>> getSetterProxyMap() {
-        return getProxyMap(Method.class, SETTER_PROXY_MAP);
+    private Map<Class<?>, Map<Method, ThreadLocalProxy<?>>> getSetterProxyMap(boolean create) {
+        return getProxyMap(Method.class, SETTER_PROXY_MAP, create);
     }
     
     private void findContextSetterMethods(Class<?> cls) {
@@ -176,7 +210,7 @@ public abstract class AbstractResourceIn
         }
         addToMap(contextMethods, contextClass, m);
         if (m.getParameterTypes()[0] != Application.class) {
-            addToMap(getSetterProxyMap(), m, 
+            addToMap(getSetterProxyMap(true), m, 
                      InjectionUtils.createThreadLocalProxy(m.getParameterTypes()[0]));
         }
     }
@@ -194,11 +228,11 @@ public abstract class AbstractResourceIn
     }
     
     public ThreadLocalProxy<?> getContextFieldProxy(Field f) {
-        return getProxy(getFieldProxyMap(), f);
+        return getProxy(getFieldProxyMap(true), f);
     }
     
     public ThreadLocalProxy<?> getContextSetterProxy(Method m) {
-        return getProxy(getSetterProxyMap(), m);
+        return getProxy(getSetterProxyMap(true), m);
     }
     
     public abstract boolean isSingleton();
@@ -215,12 +249,17 @@ public abstract class AbstractResourceIn
             if (property != null) {
                 ((Map)property).clear();
             }
+            property = bus.getProperty(CONSTRUCTOR_PROXY_MAP);
+            if (property != null) {
+                ((Map)property).clear();
+            }
         }
     }
     
     public void clearThreadLocalProxies() {
-        clearProxies(getFieldProxyMap());
-        clearProxies(getSetterProxyMap());
+        clearProxies(getFieldProxyMap(false));
+        clearProxies(getSetterProxyMap(false));
+        clearProxies(getConstructorProxyMap(false));
     }
     
     private <T> void clearProxies(Map<Class<?>, Map<T, ThreadLocalProxy<?>>> tlps) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java Wed May  1 15:42:52 2013
@@ -19,14 +19,23 @@
 
 package org.apache.cxf.jaxrs.model;
 
+import java.util.Map;
+
 import org.apache.cxf.Bus;
+import org.apache.cxf.jaxrs.impl.tl.ThreadLocalProxy;
 
 public class ProviderInfo<T> extends AbstractResourceInfo {
 
     private T provider;
     
     public ProviderInfo(T provider, Bus bus) {
-        super(provider.getClass(), provider.getClass(), true, bus);
+        this(provider, null, bus);
+    }
+    
+    public ProviderInfo(T provider, 
+                        Map<Class<?>, ThreadLocalProxy<?>> constructorProxies, 
+                        Bus bus) {
+        super(provider.getClass(), provider.getClass(), true, true, constructorProxies, bus);
         this.provider = provider;
     }
     

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringResourceFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringResourceFactory.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringResourceFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringResourceFactory.java Wed May  1 15:42:52 2013
@@ -71,7 +71,7 @@ public class SpringResourceFactory imple
      * {@inheritDoc}
      */
     public Object getInstance(Message m) {
-        Object[] values = ResourceUtils.createConstructorArguments(c, m);
+        Object[] values = ResourceUtils.createConstructorArguments(c, m, !isSingleton());
         Object instance = values.length > 0 ? ac.getBean(beanId, values) : ac.getBean(beanId);
         if (!isSingleton || m == null) {
             InjectionUtils.invokeLifeCycleMethod(instance, postConstructMethod);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java Wed May  1 15:42:52 2013
@@ -963,6 +963,7 @@ public final class InjectionUtils {
         if (resource.contextsAvailable()) {
             injectContextMethods(requestObject, resource, message);
             injectContextFields(requestObject, resource, message);
+            injectConstructorProxies(requestObject, resource, message);
         }
     }
     
@@ -1008,6 +1009,20 @@ public final class InjectionUtils {
         }
     }
     
+    @SuppressWarnings("unchecked")
+    public static void injectConstructorProxies(Object o,
+                                                AbstractResourceInfo cri,
+                                                Message m) {
+        
+        Map<Class<?>, ThreadLocalProxy<?>> proxies = cri.getConstructorProxies();
+        if (proxies != null) {
+            for (Map.Entry<Class<?>, ThreadLocalProxy<?>> entry : proxies.entrySet()) {
+                Object value = JAXRSUtils.createContextValue(m, entry.getKey(), entry.getKey());
+                ((ThreadLocalProxy<Object>)entry.getValue()).set(value);
+            }
+        }
+    }
+    
     public static MultivaluedMap<String, Object> extractValuesFromBean(Object bean, String baseName) {
         MultivaluedMap<String, Object> values = new MetadataMap<String, Object>();
         fillInValuesFromBean(bean, baseName, values);

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java Wed May  1 15:42:52 2013
@@ -614,7 +614,7 @@ public final class ResourceUtils {
         return op;
     }
     
-    public static Object[] createConstructorArguments(Constructor<?> c, Message m) {
+    public static Object[] createConstructorArguments(Constructor<?> c, Message m, boolean perRequest) {
         Class<?>[] params = c.getParameterTypes();
         Annotation[][] anns = c.getParameterAnnotations();
         Type[] genericTypes = c.getGenericParameterTypes();
@@ -624,8 +624,14 @@ public final class ResourceUtils {
         Object[] values = new Object[params.length];
         for (int i = 0; i < params.length; i++) {
             if (AnnotationUtils.getAnnotation(anns[i], Context.class) != null) {
-                values[i] = JAXRSUtils.createContextValue(m, genericTypes[i], params[i]);
+                if (perRequest) {
+                    values[i] = JAXRSUtils.createContextValue(m, genericTypes[i], params[i]);
+                } else {
+                    values[i] = InjectionUtils.createThreadLocalProxy(params[i]);
+                }
             } else {
+                // this branch won't execute for singletons given that the found constructor
+                // is guaranteed to have only Context parameters, if any, for singletons
                 Parameter p = ResourceUtils.getParameter(i, anns[i], params[i]);
                 values[i] = JAXRSUtils.createHttpParameterValue(
                                 p, params[i], genericTypes[i], anns[i], m, templateValues, null);
@@ -646,27 +652,31 @@ public final class ResourceUtils {
         List<Object> providers = new ArrayList<Object>();
         Map<Class<?>, ResourceProvider> map = new HashMap<Class<?>, ResourceProvider>();
         
-        // Note, app.getClasse() returns a list of per-resource classes
+        // Note, app.getClasses() returns a list of per-request classes
         // or singleton provider classes
-        for (Class<?> c : app.getClasses()) {
-            if (isValidApplicationClass(c, singletons)) {
-                if (isValidProvider(c)) {
+        for (Class<?> cls : app.getClasses()) {
+            if (isValidApplicationClass(cls, singletons)) {
+                if (isValidProvider(cls)) {
                     try {
-                        providers.add(c.newInstance());
+                        Constructor<?> c = ResourceUtils.findResourceConstructor(cls, false);
+                        if (c.getParameterTypes().length == 0) {
+                            providers.add(c.newInstance());
+                        } else {
+                            providers.add(c);
+                        }
                     } catch (Throwable ex) {
-                        throw new RuntimeException("Provider " + c.getName() + " can not be created", ex); 
+                        throw new RuntimeException("Provider " + cls.getName() + " can not be created", ex); 
                     }
                 } else {
-                    resourceClasses.add(c);
-                    map.put(c, new PerRequestResourceProvider(c));
+                    resourceClasses.add(cls);
+                    map.put(cls, new PerRequestResourceProvider(cls));
                 }
             }
         }
         
         // we can get either a provider or resource class here        
         for (Object o : singletons) {
-            boolean isProvider = o.getClass().getAnnotation(Provider.class) != null;
-            if (isProvider) {
+            if (isValidProvider(o.getClass())) {
                 providers.add(o);
             } else {
                 resourceClasses.add(o.getClass());

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplication.java Wed May  1 15:42:52 2013
@@ -18,14 +18,19 @@
  */
 package org.apache.cxf.systest.jaxrs;
 
+import java.io.IOException;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import javax.servlet.ServletContext;
 import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
 
 @ApplicationPath("/thebooks")
 public class BookApplication extends Application {
@@ -49,6 +54,7 @@ public class BookApplication extends App
         classes.add(org.apache.cxf.systest.jaxrs.BookStorePerRequest.class);
         classes.add(org.apache.cxf.systest.jaxrs.jaxws.BookStoreJaxrsJaxws.class);
         classes.add(org.apache.cxf.systest.jaxrs.RuntimeExceptionMapper.class);
+        classes.add(BookRequestFilter.class);
         return classes;
     }
 
@@ -76,4 +82,21 @@ public class BookApplication extends App
         }
         defaultId = Long.valueOf(sb.toString());
     }
+    
+    public static class BookRequestFilter implements ContainerRequestFilter {
+        private UriInfo ui;
+        
+        public BookRequestFilter(@Context UriInfo ui) {
+            this.ui = ui;
+        }
+        
+        @Override
+        public void filter(ContainerRequestContext context) throws IOException {
+            if (ui.getRequestUri().toString().endsWith("/application11/thebooks/bookstore2/bookheaders")) {
+                context.getHeaders().put("BOOK", Arrays.asList("1", "2", "3"));    
+            }
+            
+        }
+        
+    }
 }

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerNonSpringBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerNonSpringBookTest.java?rev=1478057&r1=1478056&r2=1478057&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerNonSpringBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerNonSpringBookTest.java Wed May  1 15:42:52 2013
@@ -154,6 +154,15 @@ public class JAXRSClientServerNonSpringB
     }
     
     @Test
+    public void testGetBook123Application11PerRequest() throws Exception {
+        WebClient wc = WebClient.create("http://localhost:" + PORT + "/application11/thebooks/bookstore2/bookheaders");
+        wc.accept("application/xml");
+        Book book = wc.get(Book.class);
+        assertEquals("CXF in Action", book.getName());
+        assertEquals(123L, book.getId());
+    }
+    
+    @Test
     public void testGetNonExistentBook() throws Exception {
         WebClient wc = WebClient.create("http://localhost:" + PORT 
                                         + "/application11/thebooks/bookstore/books/321");