You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by as...@apache.org on 2014/01/23 15:53:48 UTC
svn commit: r1560703 - in /cxf/branches/2.7.x-fixes:
api/src/main/java/org/apache/cxf/service/invoker/
rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/
systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
Author: ashakirin
Date: Thu Jan 23 14:53:47 2014
New Revision: 1560703
URL: http://svn.apache.org/r1560703
Log:
Backported [CXF-5512]: @UseAsyncMethod annotation doesn't work for classes implementing Provider<T>
Modified:
cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
Modified: cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java (original)
+++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java Thu Jan 23 14:53:47 2014
@@ -66,7 +66,7 @@ public abstract class AbstractInvoker im
params = new MessageContentsList(o);
}
- m = adjustMethodAndParams(m, exchange, params);
+ m = adjustMethodAndParams(m, exchange, params, serviceObject.getClass());
//Method m = (Method)bop.getOperationInfo().getProperty(Method.class.getName());
m = matchMethod(m, serviceObject);
@@ -80,7 +80,8 @@ public abstract class AbstractInvoker im
protected Method adjustMethodAndParams(Method m,
Exchange ex,
- List<Object> params) {
+ List<Object> params,
+ Class<?> serviceObjectClass) {
//nothing to do
return m;
}
Modified: cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java (original)
+++ cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java Thu Jan 23 14:53:47 2014
@@ -20,6 +20,8 @@
package org.apache.cxf.jaxws;
import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -30,6 +32,7 @@ import java.util.concurrent.ExecutionExc
import javax.activation.DataHandler;
import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Provider;
import javax.xml.ws.Response;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.MessageContext.Scope;
@@ -52,6 +55,7 @@ import org.apache.cxf.message.FaultMode;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageContentsList;
import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.service.factory.ServiceConstructionException;
import org.apache.cxf.service.invoker.Factory;
import org.apache.cxf.service.invoker.FactoryInvoker;
import org.apache.cxf.service.invoker.SingletonFactory;
@@ -77,18 +81,24 @@ public abstract class AbstractJAXWSMetho
}
return null;
}
- protected Method adjustMethodAndParams(Method m, Exchange ex, List<Object> params) {
+
+ @Override
+ protected Method adjustMethodAndParams(Method mOriginal, Exchange ex, List<Object> params,
+ Class<?> serviceObjectClass) {
+ // If class implements Provider<T> interface, use overriden method from service object class
+ // to check UseAsyncMethod annotation
+ Method mso = getProviderServiceObjectMethod(mOriginal, serviceObjectClass);
- UseAsyncMethod uam = m.getAnnotation(UseAsyncMethod.class);
+ UseAsyncMethod uam = mso.getAnnotation(UseAsyncMethod.class);
if (uam != null) {
BindingOperationInfo bop = ex.getBindingOperationInfo();
Method ret = bop.getProperty(ASYNC_METHOD, Method.class);
if (ret == null) {
- Class<?> ptypes[] = new Class<?>[m.getParameterTypes().length + 1];
- System.arraycopy(m.getParameterTypes(), 0, ptypes, 0, m.getParameterTypes().length);
- ptypes[m.getParameterTypes().length] = AsyncHandler.class;
+ Class<?> ptypes[] = new Class<?>[mso.getParameterTypes().length + 1];
+ System.arraycopy(mso.getParameterTypes(), 0, ptypes, 0, mso.getParameterTypes().length);
+ ptypes[mso.getParameterTypes().length] = AsyncHandler.class;
try {
- ret = m.getDeclaringClass().getMethod(m.getName() + "Async", ptypes);
+ ret = mso.getDeclaringClass().getMethod(mso.getName() + "Async", ptypes);
bop.setProperty(ASYNC_METHOD, ret);
} catch (Throwable t) {
//ignore
@@ -115,9 +125,52 @@ public abstract class AbstractJAXWSMetho
}
}
}
- return m;
+ return mOriginal;
}
+ private Method getProviderServiceObjectMethod(Method m, Class<?> serviceObjectClass) {
+ if (!Provider.class.isAssignableFrom(serviceObjectClass)) {
+ return m;
+ }
+ Class<?> currentSvcClass = serviceObjectClass;
+ Class<?> genericType = null;
+
+ while (currentSvcClass != null) {
+ genericType = getProviderGenericType(currentSvcClass);
+ if (genericType != null) {
+ break;
+ }
+ // Check superclass until top
+ currentSvcClass = currentSvcClass.getSuperclass();
+ }
+ // Should never happens
+ if (genericType == null) {
+ return m;
+ }
+ try {
+ return serviceObjectClass.getMethod("invoke", genericType);
+ } catch (Exception e) {
+ throw new ServiceConstructionException(e);
+ }
+ }
+
+ private Class<?> getProviderGenericType(Class<?> svcClass) {
+ Type[] interfaces = svcClass.getGenericInterfaces();
+ for (Type interfaceType : interfaces) {
+ if (interfaceType instanceof ParameterizedType) {
+ ParameterizedType paramInterface = (ParameterizedType)interfaceType;
+ if (!paramInterface.getRawType().equals(Provider.class)) {
+ continue;
+ }
+ Type[] typeArgs = paramInterface.getActualTypeArguments();
+ if (typeArgs.length > 0) {
+ return (Class<?>)typeArgs[0];
+ }
+ }
+ }
+ return null;
+ }
+
class JaxwsServerHandler implements AsyncHandler<Object> {
Response<Object> r;
Continuation continuation;
Modified: cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java (original)
+++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java Thu Jan 23 14:53:47 2014
@@ -19,6 +19,7 @@
package org.apache.cxf.systest.jaxws;
+import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@@ -41,8 +42,10 @@ import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import javax.xml.namespace.QName;
+import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Dispatch;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Response;
import javax.xml.ws.Service;
@@ -63,6 +66,7 @@ import org.apache.cxf.frontend.ClientPro
import org.apache.cxf.helpers.XMLUtils;
import org.apache.cxf.helpers.XPathUtils;
import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.hello_world_soap_http.BadRecordLitFault;
@@ -76,7 +80,6 @@ import org.apache.hello_world_soap_http.
import org.apache.hello_world_soap_http.types.BareDocumentResponse;
import org.apache.hello_world_soap_http.types.GreetMeLaterResponse;
import org.apache.hello_world_soap_http.types.GreetMeResponse;
-
import org.junit.BeforeClass;
import org.junit.Test;
@@ -1057,4 +1060,19 @@ public class ClientServerTest extends Ab
assertEquals("Hello World", resp);
}
+ @Test
+ public void testEchoProviderAsync() throws Exception {
+ String requestString = "<echo/>";
+ Service service = Service.create(serviceName);
+ service.addPort(fakePortName, javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
+ "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider");
+ Dispatch<StreamSource> dispatcher = service.createDispatch(fakePortName,
+ StreamSource.class,
+ Service.Mode.PAYLOAD);
+
+ StreamSource request = new StreamSource(new ByteArrayInputStream(requestString.getBytes()));
+ StreamSource response = dispatcher.invoke(request);
+
+ assertEquals(requestString, StaxUtils.toString(response));
+ }
}
Modified: cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java (original)
+++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java Thu Jan 23 14:53:47 2014
@@ -25,8 +25,14 @@ import java.util.List;
import java.util.concurrent.Future;
import javax.jws.WebService;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Endpoint;
+import javax.xml.ws.Provider;
+import javax.xml.ws.Service;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceProvider;
import org.apache.cxf.annotations.UseAsyncMethod;
import org.apache.cxf.interceptor.URIMappingInterceptor;
@@ -60,6 +66,10 @@ public class Server extends AbstractBusT
address = "http://localhost:" + PORT + "/SoapContext/AsyncSoapPort";
eps.add(Endpoint.publish(address, implementor));
+ implementor = new AsyncEchoProvider();
+ address = "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider";
+ eps.add(Endpoint.publish(address, implementor));
+
implementor = new GreeterImplMultiPort();
address = "http://localhost:" + PORT + "/MultiPort/GreeterPort";
eps.add(Endpoint.publish(address, implementor));
@@ -146,6 +156,33 @@ public class Server extends AbstractBusT
}
}
+ @WebServiceProvider
+ @ServiceMode(value = Service.Mode.PAYLOAD)
+ public class AsyncEchoProvider implements Provider<StreamSource> {
+
+ @Override
+ @UseAsyncMethod
+ public StreamSource invoke(StreamSource request) {
+ throw new RuntimeException("Should be async");
+ }
+
+ public Future<?> invokeAsync(final StreamSource s, final AsyncHandler<Source> asyncHandler) {
+ final ServerAsyncResponse<Source> r = new ServerAsyncResponse<Source>();
+ new Thread() {
+ public void run() {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ r.set(s);
+ asyncHandler.handleResponse(r);
+ }
+ } .start();
+ return r;
+ }
+ }
+
public static void main(String[] args) {
try {
Server s = new Server();
RE: svn commit: r1560703 - in /cxf/branches/2.7.x-fixes:
api/src/main/java/org/apache/cxf/service/invoker/
rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/
systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
Posted by Andrei Shakirin <as...@talend.com>.
Yep, will update that.
Regards,
Andrei.
> -----Original Message-----
> From: Alessio Soldano [mailto:asoldano@redhat.com]
> Sent: Donnerstag, 23. Januar 2014 16:46
> To: dev@cxf.apache.org
> Cc: Daniel Kulp; ashakirin@apache.org
> Subject: Re: svn commit: r1560703 - in /cxf/branches/2.7.x-fixes:
> api/src/main/java/org/apache/cxf/service/invoker/
> rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/
> systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
>
> On 23/01/14 16:01, Daniel Kulp wrote:
> > Andrei,
> >
> > This changes a protected method on a Abstract class that I believe either
> the JBoss folks or TomEE folks are subclassing.
> Currently, the JBossWS integration directly calls the
> adjustMethodAndParams method from a custom invoker extending
> JAXWSMethodInvoker and overriding invoke(Exchange exchange, Object o).
> So I'd also prefer what Dan suggests below on 2.7.x ;-)
>
> Thanks
>
> Alessio
>
>
> > That's a concern to me as that would be a backwards compatible break.
> >
> > On 2.7.x, can we update the new method to handle when
> serviceObjectClass is null and re-introduce the original method calling the
> new one with null?
> >
> >
> > Dan
> >
> >
> >
> > On Jan 23, 2014, at 9:53 AM, ashakirin@apache.org wrote:
> >
> >> Author: ashakirin
> >> Date: Thu Jan 23 14:53:47 2014
> >> New Revision: 1560703
> >>
> >> URL: http://svn.apache.org/r1560703
> >> Log:
> >> Backported [CXF-5512]: @UseAsyncMethod annotation doesn't work for
> >> classes implementing Provider<T>
> >>
> >> Modified:
> >> cxf/branches/2.7.x-
> fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.jav
> a
> >> cxf/branches/2.7.x-
> fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXW
> SMethodInvoker.java
> >> cxf/branches/2.7.x-
> fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServ
> erTest.java
> >>
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/Server.java
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/inv
> >> oker/AbstractInvoker.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/ja
> >>
> va/org/apache/cxf/service/invoker/AbstractInvoker.java?rev=1560703&r1
> >> =1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/inv
> >> oker/AbstractInvoker.java (original)
> >> +++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service
> >> +++ /invoker/AbstractInvoker.java Thu Jan 23 14:53:47 2014
> >> @@ -66,7 +66,7 @@ public abstract class AbstractInvoker im
> >> params = new MessageContentsList(o);
> >> }
> >>
> >> - m = adjustMethodAndParams(m, exchange, params);
> >> + m = adjustMethodAndParams(m, exchange, params,
> >> + serviceObject.getClass());
> >>
> >> //Method m =
> (Method)bop.getOperationInfo().getProperty(Method.class.getName());
> >> m = matchMethod(m, serviceObject); @@ -80,7 +80,8 @@
> >> public abstract class AbstractInvoker im
> >>
> >> protected Method adjustMethodAndParams(Method m,
> >> Exchange ex,
> >> - List<Object> params) {
> >> + List<Object> params,
> >> + Class<?>
> >> + serviceObjectClass) {
> >> //nothing to do
> >> return m;
> >> }
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/c
> >> xf/jaxws/AbstractJAXWSMethodInvoker.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jax
> >>
> ws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.jav
> a
> >> ?rev=1560703&r1=1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/c
> >> xf/jaxws/AbstractJAXWSMethodInvoker.java (original)
> >> +++ cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apac
> >> +++ he/cxf/jaxws/AbstractJAXWSMethodInvoker.java Thu Jan 23
> 14:53:47
> >> +++ 2014
> >> @@ -20,6 +20,8 @@
> >> package org.apache.cxf.jaxws;
> >>
> >> import java.lang.reflect.Method;
> >> +import java.lang.reflect.ParameterizedType;
> >> +import java.lang.reflect.Type;
> >> import java.util.ArrayList;
> >> import java.util.Collection;
> >> import java.util.HashMap;
> >> @@ -30,6 +32,7 @@ import java.util.concurrent.ExecutionExc
> >>
> >> import javax.activation.DataHandler;
> >> import javax.xml.ws.AsyncHandler;
> >> +import javax.xml.ws.Provider;
> >> import javax.xml.ws.Response;
> >> import javax.xml.ws.handler.MessageContext;
> >> import javax.xml.ws.handler.MessageContext.Scope;
> >> @@ -52,6 +55,7 @@ import org.apache.cxf.message.FaultMode; import
> >> org.apache.cxf.message.Message; import
> >> org.apache.cxf.message.MessageContentsList;
> >> import org.apache.cxf.message.MessageImpl;
> >> +import org.apache.cxf.service.factory.ServiceConstructionException;
> >> import org.apache.cxf.service.invoker.Factory;
> >> import org.apache.cxf.service.invoker.FactoryInvoker;
> >> import org.apache.cxf.service.invoker.SingletonFactory;
> >> @@ -77,18 +81,24 @@ public abstract class AbstractJAXWSMetho
> >> }
> >> return null;
> >> }
> >> - protected Method adjustMethodAndParams(Method m, Exchange ex,
> List<Object> params) {
> >> +
> >> + @Override
> >> + protected Method adjustMethodAndParams(Method mOriginal,
> Exchange ex, List<Object> params,
> >> + Class<?> serviceObjectClass) {
> >> + // If class implements Provider<T> interface, use overriden method
> from service object class
> >> + // to check UseAsyncMethod annotation
> >> + Method mso = getProviderServiceObjectMethod(mOriginal,
> >> + serviceObjectClass);
> >>
> >> - UseAsyncMethod uam = m.getAnnotation(UseAsyncMethod.class);
> >> + UseAsyncMethod uam =
> >> + mso.getAnnotation(UseAsyncMethod.class);
> >> if (uam != null) {
> >> BindingOperationInfo bop = ex.getBindingOperationInfo();
> >> Method ret = bop.getProperty(ASYNC_METHOD, Method.class);
> >> if (ret == null) {
> >> - Class<?> ptypes[] = new
> Class<?>[m.getParameterTypes().length + 1];
> >> - System.arraycopy(m.getParameterTypes(), 0, ptypes, 0,
> m.getParameterTypes().length);
> >> - ptypes[m.getParameterTypes().length] = AsyncHandler.class;
> >> + Class<?> ptypes[] = new
> Class<?>[mso.getParameterTypes().length + 1];
> >> + System.arraycopy(mso.getParameterTypes(), 0, ptypes, 0,
> mso.getParameterTypes().length);
> >> + ptypes[mso.getParameterTypes().length] =
> >> + AsyncHandler.class;
> >> try {
> >> - ret = m.getDeclaringClass().getMethod(m.getName() +
> "Async", ptypes);
> >> + ret =
> >> + mso.getDeclaringClass().getMethod(mso.getName() + "Async",
> ptypes);
> >> bop.setProperty(ASYNC_METHOD, ret);
> >> } catch (Throwable t) {
> >> //ignore
> >> @@ -115,9 +125,52 @@ public abstract class AbstractJAXWSMetho
> >> }
> >> }
> >> }
> >> - return m;
> >> + return mOriginal;
> >> }
> >>
> >> + private Method getProviderServiceObjectMethod(Method m,
> Class<?> serviceObjectClass) {
> >> + if (!Provider.class.isAssignableFrom(serviceObjectClass)) {
> >> + return m;
> >> + }
> >> + Class<?> currentSvcClass = serviceObjectClass;
> >> + Class<?> genericType = null;
> >> +
> >> + while (currentSvcClass != null) {
> >> + genericType = getProviderGenericType(currentSvcClass);
> >> + if (genericType != null) {
> >> + break;
> >> + }
> >> + // Check superclass until top
> >> + currentSvcClass = currentSvcClass.getSuperclass();
> >> + }
> >> + // Should never happens
> >> + if (genericType == null) {
> >> + return m;
> >> + }
> >> + try {
> >> + return serviceObjectClass.getMethod("invoke", genericType);
> >> + } catch (Exception e) {
> >> + throw new ServiceConstructionException(e);
> >> + }
> >> + }
> >> +
> >> + private Class<?> getProviderGenericType(Class<?> svcClass) {
> >> + Type[] interfaces = svcClass.getGenericInterfaces();
> >> + for (Type interfaceType : interfaces) {
> >> + if (interfaceType instanceof ParameterizedType) {
> >> + ParameterizedType paramInterface =
> (ParameterizedType)interfaceType;
> >> + if (!paramInterface.getRawType().equals(Provider.class)) {
> >> + continue;
> >> + }
> >> + Type[] typeArgs = paramInterface.getActualTypeArguments();
> >> + if (typeArgs.length > 0) {
> >> + return (Class<?>)typeArgs[0];
> >> + }
> >> + }
> >> + }
> >> + return null;
> >> + }
> >> +
> >> class JaxwsServerHandler implements AsyncHandler<Object> {
> >> Response<Object> r;
> >> Continuation continuation;
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/ClientServerTest.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/
> >> src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java?rev=
> >> 1560703&r1=1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/ClientServerTest.java (original)
> >> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/
> >> +++ cxf/systest/jaxws/ClientServerTest.java Thu Jan 23 14:53:47 2014
> >> @@ -19,6 +19,7 @@
> >>
> >> package org.apache.cxf.systest.jaxws;
> >>
> >> +import java.io.ByteArrayInputStream;
> >> import java.io.InputStream;
> >> import java.lang.reflect.InvocationHandler;
> >> import java.lang.reflect.Method;
> >> @@ -41,8 +42,10 @@ import java.util.logging.Logger; import
> >> java.util.zip.GZIPInputStream;
> >>
> >> import javax.xml.namespace.QName;
> >> +import javax.xml.transform.stream.StreamSource;
> >> import javax.xml.ws.AsyncHandler;
> >> import javax.xml.ws.BindingProvider;
> >> +import javax.xml.ws.Dispatch;
> >> import javax.xml.ws.Endpoint;
> >> import javax.xml.ws.Response;
> >> import javax.xml.ws.Service;
> >> @@ -63,6 +66,7 @@ import org.apache.cxf.frontend.ClientPro import
> >> org.apache.cxf.helpers.XMLUtils; import
> >> org.apache.cxf.helpers.XPathUtils;
> >> import org.apache.cxf.message.Message;
> >> +import org.apache.cxf.staxutils.StaxUtils;
> >> import
> >> org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> >> import org.apache.cxf.transport.http.HTTPConduit;
> >> import org.apache.hello_world_soap_http.BadRecordLitFault;
> >> @@ -76,7 +80,6 @@ import org.apache.hello_world_soap_http.
> >> import
> org.apache.hello_world_soap_http.types.BareDocumentResponse;
> >> import
> org.apache.hello_world_soap_http.types.GreetMeLaterResponse;
> >> import org.apache.hello_world_soap_http.types.GreetMeResponse;
> >> -
> >> import org.junit.BeforeClass;
> >> import org.junit.Test;
> >>
> >> @@ -1057,4 +1060,19 @@ public class ClientServerTest extends Ab
> >> assertEquals("Hello World", resp);
> >> }
> >>
> >> + @Test
> >> + public void testEchoProviderAsync() throws Exception {
> >> + String requestString = "<echo/>";
> >> + Service service = Service.create(serviceName);
> >> + service.addPort(fakePortName,
> javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
> >> + "http://localhost:" + PORT +
> "/SoapContext/AsyncEchoProvider");
> >> + Dispatch<StreamSource> dispatcher =
> service.createDispatch(fakePortName,
> >> + StreamSource.class,
> >> +
> >> + Service.Mode.PAYLOAD);
> >> +
> >> + StreamSource request = new StreamSource(new
> ByteArrayInputStream(requestString.getBytes()));
> >> + StreamSource response = dispatcher.invoke(request);
> >> +
> >> + assertEquals(requestString, StaxUtils.toString(response));
> >> + }
> >> }
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/Server.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/
> >> src/test/java/org/apache/cxf/systest/jaxws/Server.java?rev=1560703&r1
> >> =1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/Server.java (original)
> >> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/
> >> +++ cxf/systest/jaxws/Server.java Thu Jan 23 14:53:47 2014
> >> @@ -25,8 +25,14 @@ import java.util.List; import
> >> java.util.concurrent.Future;
> >>
> >> import javax.jws.WebService;
> >> +import javax.xml.transform.Source;
> >> +import javax.xml.transform.stream.StreamSource;
> >> import javax.xml.ws.AsyncHandler;
> >> import javax.xml.ws.Endpoint;
> >> +import javax.xml.ws.Provider;
> >> +import javax.xml.ws.Service;
> >> +import javax.xml.ws.ServiceMode;
> >> +import javax.xml.ws.WebServiceProvider;
> >>
> >> import org.apache.cxf.annotations.UseAsyncMethod;
> >> import org.apache.cxf.interceptor.URIMappingInterceptor;
> >> @@ -60,6 +66,10 @@ public class Server extends AbstractBusT
> >> address = "http://localhost:" + PORT +
> "/SoapContext/AsyncSoapPort";
> >> eps.add(Endpoint.publish(address, implementor));
> >>
> >> + implementor = new AsyncEchoProvider();
> >> + address = "http://localhost:" + PORT +
> "/SoapContext/AsyncEchoProvider";
> >> + eps.add(Endpoint.publish(address, implementor));
> >> +
> >> implementor = new GreeterImplMultiPort();
> >> address = "http://localhost:" + PORT + "/MultiPort/GreeterPort";
> >> eps.add(Endpoint.publish(address, implementor)); @@ -146,6
> >> +156,33 @@ public class Server extends AbstractBusT
> >> }
> >> }
> >>
> >> + @WebServiceProvider
> >> + @ServiceMode(value = Service.Mode.PAYLOAD)
> >> + public class AsyncEchoProvider implements Provider<StreamSource>
> >> + {
> >> +
> >> + @Override
> >> + @UseAsyncMethod
> >> + public StreamSource invoke(StreamSource request) {
> >> + throw new RuntimeException("Should be async");
> >> + }
> >> +
> >> + public Future<?> invokeAsync(final StreamSource s, final
> AsyncHandler<Source> asyncHandler) {
> >> + final ServerAsyncResponse<Source> r = new
> ServerAsyncResponse<Source>();
> >> + new Thread() {
> >> + public void run() {
> >> + try {
> >> + Thread.sleep(500);
> >> + } catch (InterruptedException e) {
> >> + // ignore
> >> + }
> >> + r.set(s);
> >> + asyncHandler.handleResponse(r);
> >> + }
> >> + } .start();
> >> + return r;
> >> + }
> >> + }
> >> +
> >> public static void main(String[] args) {
> >> try {
> >> Server s = new Server();
> >>
> >>
>
>
> --
> Alessio Soldano
> Web Service Lead, JBoss
RE: svn commit: r1560703 - in /cxf/branches/2.7.x-fixes:
api/src/main/java/org/apache/cxf/service/invoker/
rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/
systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
Posted by Andrei Shakirin <as...@talend.com>.
Have updated in a way suggested by Dan, however strongly said compatibility is still broken:
if users override old AbstarctInvoker.adjustMethodAndParams() and just call existing AbstarctInvoker.invoke() method, the overriding adjustMethodAndParams() will not be invoked anymore (because invoke() calls a new one with serviceObjectClass argument) - a drawback of subclassing, making dependent on internal method implementation :(
That will not be a problem in case described by Alessio, when AbstractInvoker.invoke() method is overridden and old adjustMethodAndParams() is called.
I thinking about 100% compatible solution without changing adjustMethodAndParams() signature at all:
- temporary saving serviceObjectClass into exchange;
- passing serviceObjectClass through ThreadLocal;
- repeatedly invoking of AbstractInvoker.getServiceObject() from AbstractJAXWSMethodInvoker currently causes deadlock, because PooledFactory.createObject(Exchange) tries to get Object from empty pool. This way likely will requires some additional changes/refactoring.
Does it makes sense or is it overkill and we can leave the code as it is: https://fisheye6.atlassian.com/rdiff/cxf?csid=1560923&u&N ?
Regards,
Andrei.
> -----Original Message-----
> From: Alessio Soldano [mailto:asoldano@redhat.com]
> Sent: Donnerstag, 23. Januar 2014 16:46
> To: dev@cxf.apache.org
> Cc: Daniel Kulp; ashakirin@apache.org
> Subject: Re: svn commit: r1560703 - in /cxf/branches/2.7.x-fixes:
> api/src/main/java/org/apache/cxf/service/invoker/
> rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/
> systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
>
> On 23/01/14 16:01, Daniel Kulp wrote:
> > Andrei,
> >
> > This changes a protected method on a Abstract class that I believe either
> the JBoss folks or TomEE folks are subclassing.
> Currently, the JBossWS integration directly calls the
> adjustMethodAndParams method from a custom invoker extending
> JAXWSMethodInvoker and overriding invoke(Exchange exchange, Object o).
> So I'd also prefer what Dan suggests below on 2.7.x ;-)
>
> Thanks
>
> Alessio
>
>
> > That's a concern to me as that would be a backwards compatible break.
> >
> > On 2.7.x, can we update the new method to handle when
> serviceObjectClass is null and re-introduce the original method calling the
> new one with null?
> >
> >
> > Dan
> >
> >
> >
> > On Jan 23, 2014, at 9:53 AM, ashakirin@apache.org wrote:
> >
> >> Author: ashakirin
> >> Date: Thu Jan 23 14:53:47 2014
> >> New Revision: 1560703
> >>
> >> URL: http://svn.apache.org/r1560703
> >> Log:
> >> Backported [CXF-5512]: @UseAsyncMethod annotation doesn't work for
> >> classes implementing Provider<T>
> >>
> >> Modified:
> >> cxf/branches/2.7.x-
> fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.jav
> a
> >> cxf/branches/2.7.x-
> fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXW
> SMethodInvoker.java
> >> cxf/branches/2.7.x-
> fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServ
> erTest.java
> >>
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/Server.java
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/inv
> >> oker/AbstractInvoker.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/ja
> >>
> va/org/apache/cxf/service/invoker/AbstractInvoker.java?rev=1560703&r1
> >> =1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/inv
> >> oker/AbstractInvoker.java (original)
> >> +++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service
> >> +++ /invoker/AbstractInvoker.java Thu Jan 23 14:53:47 2014
> >> @@ -66,7 +66,7 @@ public abstract class AbstractInvoker im
> >> params = new MessageContentsList(o);
> >> }
> >>
> >> - m = adjustMethodAndParams(m, exchange, params);
> >> + m = adjustMethodAndParams(m, exchange, params,
> >> + serviceObject.getClass());
> >>
> >> //Method m =
> (Method)bop.getOperationInfo().getProperty(Method.class.getName());
> >> m = matchMethod(m, serviceObject); @@ -80,7 +80,8 @@
> >> public abstract class AbstractInvoker im
> >>
> >> protected Method adjustMethodAndParams(Method m,
> >> Exchange ex,
> >> - List<Object> params) {
> >> + List<Object> params,
> >> + Class<?>
> >> + serviceObjectClass) {
> >> //nothing to do
> >> return m;
> >> }
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/c
> >> xf/jaxws/AbstractJAXWSMethodInvoker.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jax
> >>
> ws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.jav
> a
> >> ?rev=1560703&r1=1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/c
> >> xf/jaxws/AbstractJAXWSMethodInvoker.java (original)
> >> +++ cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apac
> >> +++ he/cxf/jaxws/AbstractJAXWSMethodInvoker.java Thu Jan 23
> 14:53:47
> >> +++ 2014
> >> @@ -20,6 +20,8 @@
> >> package org.apache.cxf.jaxws;
> >>
> >> import java.lang.reflect.Method;
> >> +import java.lang.reflect.ParameterizedType;
> >> +import java.lang.reflect.Type;
> >> import java.util.ArrayList;
> >> import java.util.Collection;
> >> import java.util.HashMap;
> >> @@ -30,6 +32,7 @@ import java.util.concurrent.ExecutionExc
> >>
> >> import javax.activation.DataHandler;
> >> import javax.xml.ws.AsyncHandler;
> >> +import javax.xml.ws.Provider;
> >> import javax.xml.ws.Response;
> >> import javax.xml.ws.handler.MessageContext;
> >> import javax.xml.ws.handler.MessageContext.Scope;
> >> @@ -52,6 +55,7 @@ import org.apache.cxf.message.FaultMode; import
> >> org.apache.cxf.message.Message; import
> >> org.apache.cxf.message.MessageContentsList;
> >> import org.apache.cxf.message.MessageImpl;
> >> +import org.apache.cxf.service.factory.ServiceConstructionException;
> >> import org.apache.cxf.service.invoker.Factory;
> >> import org.apache.cxf.service.invoker.FactoryInvoker;
> >> import org.apache.cxf.service.invoker.SingletonFactory;
> >> @@ -77,18 +81,24 @@ public abstract class AbstractJAXWSMetho
> >> }
> >> return null;
> >> }
> >> - protected Method adjustMethodAndParams(Method m, Exchange ex,
> List<Object> params) {
> >> +
> >> + @Override
> >> + protected Method adjustMethodAndParams(Method mOriginal,
> Exchange ex, List<Object> params,
> >> + Class<?> serviceObjectClass) {
> >> + // If class implements Provider<T> interface, use overriden method
> from service object class
> >> + // to check UseAsyncMethod annotation
> >> + Method mso = getProviderServiceObjectMethod(mOriginal,
> >> + serviceObjectClass);
> >>
> >> - UseAsyncMethod uam = m.getAnnotation(UseAsyncMethod.class);
> >> + UseAsyncMethod uam =
> >> + mso.getAnnotation(UseAsyncMethod.class);
> >> if (uam != null) {
> >> BindingOperationInfo bop = ex.getBindingOperationInfo();
> >> Method ret = bop.getProperty(ASYNC_METHOD, Method.class);
> >> if (ret == null) {
> >> - Class<?> ptypes[] = new
> Class<?>[m.getParameterTypes().length + 1];
> >> - System.arraycopy(m.getParameterTypes(), 0, ptypes, 0,
> m.getParameterTypes().length);
> >> - ptypes[m.getParameterTypes().length] = AsyncHandler.class;
> >> + Class<?> ptypes[] = new
> Class<?>[mso.getParameterTypes().length + 1];
> >> + System.arraycopy(mso.getParameterTypes(), 0, ptypes, 0,
> mso.getParameterTypes().length);
> >> + ptypes[mso.getParameterTypes().length] =
> >> + AsyncHandler.class;
> >> try {
> >> - ret = m.getDeclaringClass().getMethod(m.getName() +
> "Async", ptypes);
> >> + ret =
> >> + mso.getDeclaringClass().getMethod(mso.getName() + "Async",
> ptypes);
> >> bop.setProperty(ASYNC_METHOD, ret);
> >> } catch (Throwable t) {
> >> //ignore
> >> @@ -115,9 +125,52 @@ public abstract class AbstractJAXWSMetho
> >> }
> >> }
> >> }
> >> - return m;
> >> + return mOriginal;
> >> }
> >>
> >> + private Method getProviderServiceObjectMethod(Method m,
> Class<?> serviceObjectClass) {
> >> + if (!Provider.class.isAssignableFrom(serviceObjectClass)) {
> >> + return m;
> >> + }
> >> + Class<?> currentSvcClass = serviceObjectClass;
> >> + Class<?> genericType = null;
> >> +
> >> + while (currentSvcClass != null) {
> >> + genericType = getProviderGenericType(currentSvcClass);
> >> + if (genericType != null) {
> >> + break;
> >> + }
> >> + // Check superclass until top
> >> + currentSvcClass = currentSvcClass.getSuperclass();
> >> + }
> >> + // Should never happens
> >> + if (genericType == null) {
> >> + return m;
> >> + }
> >> + try {
> >> + return serviceObjectClass.getMethod("invoke", genericType);
> >> + } catch (Exception e) {
> >> + throw new ServiceConstructionException(e);
> >> + }
> >> + }
> >> +
> >> + private Class<?> getProviderGenericType(Class<?> svcClass) {
> >> + Type[] interfaces = svcClass.getGenericInterfaces();
> >> + for (Type interfaceType : interfaces) {
> >> + if (interfaceType instanceof ParameterizedType) {
> >> + ParameterizedType paramInterface =
> (ParameterizedType)interfaceType;
> >> + if (!paramInterface.getRawType().equals(Provider.class)) {
> >> + continue;
> >> + }
> >> + Type[] typeArgs = paramInterface.getActualTypeArguments();
> >> + if (typeArgs.length > 0) {
> >> + return (Class<?>)typeArgs[0];
> >> + }
> >> + }
> >> + }
> >> + return null;
> >> + }
> >> +
> >> class JaxwsServerHandler implements AsyncHandler<Object> {
> >> Response<Object> r;
> >> Continuation continuation;
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/ClientServerTest.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/
> >> src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java?rev=
> >> 1560703&r1=1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/ClientServerTest.java (original)
> >> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/
> >> +++ cxf/systest/jaxws/ClientServerTest.java Thu Jan 23 14:53:47 2014
> >> @@ -19,6 +19,7 @@
> >>
> >> package org.apache.cxf.systest.jaxws;
> >>
> >> +import java.io.ByteArrayInputStream;
> >> import java.io.InputStream;
> >> import java.lang.reflect.InvocationHandler;
> >> import java.lang.reflect.Method;
> >> @@ -41,8 +42,10 @@ import java.util.logging.Logger; import
> >> java.util.zip.GZIPInputStream;
> >>
> >> import javax.xml.namespace.QName;
> >> +import javax.xml.transform.stream.StreamSource;
> >> import javax.xml.ws.AsyncHandler;
> >> import javax.xml.ws.BindingProvider;
> >> +import javax.xml.ws.Dispatch;
> >> import javax.xml.ws.Endpoint;
> >> import javax.xml.ws.Response;
> >> import javax.xml.ws.Service;
> >> @@ -63,6 +66,7 @@ import org.apache.cxf.frontend.ClientPro import
> >> org.apache.cxf.helpers.XMLUtils; import
> >> org.apache.cxf.helpers.XPathUtils;
> >> import org.apache.cxf.message.Message;
> >> +import org.apache.cxf.staxutils.StaxUtils;
> >> import
> >> org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> >> import org.apache.cxf.transport.http.HTTPConduit;
> >> import org.apache.hello_world_soap_http.BadRecordLitFault;
> >> @@ -76,7 +80,6 @@ import org.apache.hello_world_soap_http.
> >> import
> org.apache.hello_world_soap_http.types.BareDocumentResponse;
> >> import
> org.apache.hello_world_soap_http.types.GreetMeLaterResponse;
> >> import org.apache.hello_world_soap_http.types.GreetMeResponse;
> >> -
> >> import org.junit.BeforeClass;
> >> import org.junit.Test;
> >>
> >> @@ -1057,4 +1060,19 @@ public class ClientServerTest extends Ab
> >> assertEquals("Hello World", resp);
> >> }
> >>
> >> + @Test
> >> + public void testEchoProviderAsync() throws Exception {
> >> + String requestString = "<echo/>";
> >> + Service service = Service.create(serviceName);
> >> + service.addPort(fakePortName,
> javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
> >> + "http://localhost:" + PORT +
> "/SoapContext/AsyncEchoProvider");
> >> + Dispatch<StreamSource> dispatcher =
> service.createDispatch(fakePortName,
> >> + StreamSource.class,
> >> +
> >> + Service.Mode.PAYLOAD);
> >> +
> >> + StreamSource request = new StreamSource(new
> ByteArrayInputStream(requestString.getBytes()));
> >> + StreamSource response = dispatcher.invoke(request);
> >> +
> >> + assertEquals(requestString, StaxUtils.toString(response));
> >> + }
> >> }
> >>
> >> Modified:
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/Server.java
> >> URL:
> >> http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/
> >> src/test/java/org/apache/cxf/systest/jaxws/Server.java?rev=1560703&r1
> >> =1560702&r2=1560703&view=diff
> >>
> ==========================================================
> ===========
> >> =========
> >> ---
> >> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/
> >> systest/jaxws/Server.java (original)
> >> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/
> >> +++ cxf/systest/jaxws/Server.java Thu Jan 23 14:53:47 2014
> >> @@ -25,8 +25,14 @@ import java.util.List; import
> >> java.util.concurrent.Future;
> >>
> >> import javax.jws.WebService;
> >> +import javax.xml.transform.Source;
> >> +import javax.xml.transform.stream.StreamSource;
> >> import javax.xml.ws.AsyncHandler;
> >> import javax.xml.ws.Endpoint;
> >> +import javax.xml.ws.Provider;
> >> +import javax.xml.ws.Service;
> >> +import javax.xml.ws.ServiceMode;
> >> +import javax.xml.ws.WebServiceProvider;
> >>
> >> import org.apache.cxf.annotations.UseAsyncMethod;
> >> import org.apache.cxf.interceptor.URIMappingInterceptor;
> >> @@ -60,6 +66,10 @@ public class Server extends AbstractBusT
> >> address = "http://localhost:" + PORT +
> "/SoapContext/AsyncSoapPort";
> >> eps.add(Endpoint.publish(address, implementor));
> >>
> >> + implementor = new AsyncEchoProvider();
> >> + address = "http://localhost:" + PORT +
> "/SoapContext/AsyncEchoProvider";
> >> + eps.add(Endpoint.publish(address, implementor));
> >> +
> >> implementor = new GreeterImplMultiPort();
> >> address = "http://localhost:" + PORT + "/MultiPort/GreeterPort";
> >> eps.add(Endpoint.publish(address, implementor)); @@ -146,6
> >> +156,33 @@ public class Server extends AbstractBusT
> >> }
> >> }
> >>
> >> + @WebServiceProvider
> >> + @ServiceMode(value = Service.Mode.PAYLOAD)
> >> + public class AsyncEchoProvider implements Provider<StreamSource>
> >> + {
> >> +
> >> + @Override
> >> + @UseAsyncMethod
> >> + public StreamSource invoke(StreamSource request) {
> >> + throw new RuntimeException("Should be async");
> >> + }
> >> +
> >> + public Future<?> invokeAsync(final StreamSource s, final
> AsyncHandler<Source> asyncHandler) {
> >> + final ServerAsyncResponse<Source> r = new
> ServerAsyncResponse<Source>();
> >> + new Thread() {
> >> + public void run() {
> >> + try {
> >> + Thread.sleep(500);
> >> + } catch (InterruptedException e) {
> >> + // ignore
> >> + }
> >> + r.set(s);
> >> + asyncHandler.handleResponse(r);
> >> + }
> >> + } .start();
> >> + return r;
> >> + }
> >> + }
> >> +
> >> public static void main(String[] args) {
> >> try {
> >> Server s = new Server();
> >>
> >>
>
>
> --
> Alessio Soldano
> Web Service Lead, JBoss
Re: svn commit: r1560703 - in /cxf/branches/2.7.x-fixes: api/src/main/java/org/apache/cxf/service/invoker/
rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/ systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
Posted by Alessio Soldano <as...@redhat.com>.
On 23/01/14 16:01, Daniel Kulp wrote:
> Andrei,
>
> This changes a protected method on a Abstract class that I believe either the JBoss folks or TomEE folks are subclassing.
Currently, the JBossWS integration directly calls the
adjustMethodAndParams method from a custom invoker extending
JAXWSMethodInvoker and overriding invoke(Exchange exchange, Object o).
So I'd also prefer what Dan suggests below on 2.7.x ;-)
Thanks
Alessio
> That’s a concern to me as that would be a backwards compatible break.
>
> On 2.7.x, can we update the new method to handle when serviceObjectClass is null and re-introduce the original method calling the new one with null?
>
>
> Dan
>
>
>
> On Jan 23, 2014, at 9:53 AM, ashakirin@apache.org wrote:
>
>> Author: ashakirin
>> Date: Thu Jan 23 14:53:47 2014
>> New Revision: 1560703
>>
>> URL: http://svn.apache.org/r1560703
>> Log:
>> Backported [CXF-5512]: @UseAsyncMethod annotation doesn't work for classes implementing Provider<T>
>>
>> Modified:
>> cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
>> cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
>> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
>> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
>>
>> Modified: cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
>> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
>> ==============================================================================
>> --- cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java (original)
>> +++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java Thu Jan 23 14:53:47 2014
>> @@ -66,7 +66,7 @@ public abstract class AbstractInvoker im
>> params = new MessageContentsList(o);
>> }
>>
>> - m = adjustMethodAndParams(m, exchange, params);
>> + m = adjustMethodAndParams(m, exchange, params, serviceObject.getClass());
>>
>> //Method m = (Method)bop.getOperationInfo().getProperty(Method.class.getName());
>> m = matchMethod(m, serviceObject);
>> @@ -80,7 +80,8 @@ public abstract class AbstractInvoker im
>>
>> protected Method adjustMethodAndParams(Method m,
>> Exchange ex,
>> - List<Object> params) {
>> + List<Object> params,
>> + Class<?> serviceObjectClass) {
>> //nothing to do
>> return m;
>> }
>>
>> Modified: cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
>> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
>> ==============================================================================
>> --- cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java (original)
>> +++ cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java Thu Jan 23 14:53:47 2014
>> @@ -20,6 +20,8 @@
>> package org.apache.cxf.jaxws;
>>
>> import java.lang.reflect.Method;
>> +import java.lang.reflect.ParameterizedType;
>> +import java.lang.reflect.Type;
>> import java.util.ArrayList;
>> import java.util.Collection;
>> import java.util.HashMap;
>> @@ -30,6 +32,7 @@ import java.util.concurrent.ExecutionExc
>>
>> import javax.activation.DataHandler;
>> import javax.xml.ws.AsyncHandler;
>> +import javax.xml.ws.Provider;
>> import javax.xml.ws.Response;
>> import javax.xml.ws.handler.MessageContext;
>> import javax.xml.ws.handler.MessageContext.Scope;
>> @@ -52,6 +55,7 @@ import org.apache.cxf.message.FaultMode;
>> import org.apache.cxf.message.Message;
>> import org.apache.cxf.message.MessageContentsList;
>> import org.apache.cxf.message.MessageImpl;
>> +import org.apache.cxf.service.factory.ServiceConstructionException;
>> import org.apache.cxf.service.invoker.Factory;
>> import org.apache.cxf.service.invoker.FactoryInvoker;
>> import org.apache.cxf.service.invoker.SingletonFactory;
>> @@ -77,18 +81,24 @@ public abstract class AbstractJAXWSMetho
>> }
>> return null;
>> }
>> - protected Method adjustMethodAndParams(Method m, Exchange ex, List<Object> params) {
>> +
>> + @Override
>> + protected Method adjustMethodAndParams(Method mOriginal, Exchange ex, List<Object> params,
>> + Class<?> serviceObjectClass) {
>> + // If class implements Provider<T> interface, use overriden method from service object class
>> + // to check UseAsyncMethod annotation
>> + Method mso = getProviderServiceObjectMethod(mOriginal, serviceObjectClass);
>>
>> - UseAsyncMethod uam = m.getAnnotation(UseAsyncMethod.class);
>> + UseAsyncMethod uam = mso.getAnnotation(UseAsyncMethod.class);
>> if (uam != null) {
>> BindingOperationInfo bop = ex.getBindingOperationInfo();
>> Method ret = bop.getProperty(ASYNC_METHOD, Method.class);
>> if (ret == null) {
>> - Class<?> ptypes[] = new Class<?>[m.getParameterTypes().length + 1];
>> - System.arraycopy(m.getParameterTypes(), 0, ptypes, 0, m.getParameterTypes().length);
>> - ptypes[m.getParameterTypes().length] = AsyncHandler.class;
>> + Class<?> ptypes[] = new Class<?>[mso.getParameterTypes().length + 1];
>> + System.arraycopy(mso.getParameterTypes(), 0, ptypes, 0, mso.getParameterTypes().length);
>> + ptypes[mso.getParameterTypes().length] = AsyncHandler.class;
>> try {
>> - ret = m.getDeclaringClass().getMethod(m.getName() + "Async", ptypes);
>> + ret = mso.getDeclaringClass().getMethod(mso.getName() + "Async", ptypes);
>> bop.setProperty(ASYNC_METHOD, ret);
>> } catch (Throwable t) {
>> //ignore
>> @@ -115,9 +125,52 @@ public abstract class AbstractJAXWSMetho
>> }
>> }
>> }
>> - return m;
>> + return mOriginal;
>> }
>>
>> + private Method getProviderServiceObjectMethod(Method m, Class<?> serviceObjectClass) {
>> + if (!Provider.class.isAssignableFrom(serviceObjectClass)) {
>> + return m;
>> + }
>> + Class<?> currentSvcClass = serviceObjectClass;
>> + Class<?> genericType = null;
>> +
>> + while (currentSvcClass != null) {
>> + genericType = getProviderGenericType(currentSvcClass);
>> + if (genericType != null) {
>> + break;
>> + }
>> + // Check superclass until top
>> + currentSvcClass = currentSvcClass.getSuperclass();
>> + }
>> + // Should never happens
>> + if (genericType == null) {
>> + return m;
>> + }
>> + try {
>> + return serviceObjectClass.getMethod("invoke", genericType);
>> + } catch (Exception e) {
>> + throw new ServiceConstructionException(e);
>> + }
>> + }
>> +
>> + private Class<?> getProviderGenericType(Class<?> svcClass) {
>> + Type[] interfaces = svcClass.getGenericInterfaces();
>> + for (Type interfaceType : interfaces) {
>> + if (interfaceType instanceof ParameterizedType) {
>> + ParameterizedType paramInterface = (ParameterizedType)interfaceType;
>> + if (!paramInterface.getRawType().equals(Provider.class)) {
>> + continue;
>> + }
>> + Type[] typeArgs = paramInterface.getActualTypeArguments();
>> + if (typeArgs.length > 0) {
>> + return (Class<?>)typeArgs[0];
>> + }
>> + }
>> + }
>> + return null;
>> + }
>> +
>> class JaxwsServerHandler implements AsyncHandler<Object> {
>> Response<Object> r;
>> Continuation continuation;
>>
>> Modified: cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
>> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java?rev=1560703&r1=1560702&r2=1560703&view=diff
>> ==============================================================================
>> --- cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java (original)
>> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java Thu Jan 23 14:53:47 2014
>> @@ -19,6 +19,7 @@
>>
>> package org.apache.cxf.systest.jaxws;
>>
>> +import java.io.ByteArrayInputStream;
>> import java.io.InputStream;
>> import java.lang.reflect.InvocationHandler;
>> import java.lang.reflect.Method;
>> @@ -41,8 +42,10 @@ import java.util.logging.Logger;
>> import java.util.zip.GZIPInputStream;
>>
>> import javax.xml.namespace.QName;
>> +import javax.xml.transform.stream.StreamSource;
>> import javax.xml.ws.AsyncHandler;
>> import javax.xml.ws.BindingProvider;
>> +import javax.xml.ws.Dispatch;
>> import javax.xml.ws.Endpoint;
>> import javax.xml.ws.Response;
>> import javax.xml.ws.Service;
>> @@ -63,6 +66,7 @@ import org.apache.cxf.frontend.ClientPro
>> import org.apache.cxf.helpers.XMLUtils;
>> import org.apache.cxf.helpers.XPathUtils;
>> import org.apache.cxf.message.Message;
>> +import org.apache.cxf.staxutils.StaxUtils;
>> import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
>> import org.apache.cxf.transport.http.HTTPConduit;
>> import org.apache.hello_world_soap_http.BadRecordLitFault;
>> @@ -76,7 +80,6 @@ import org.apache.hello_world_soap_http.
>> import org.apache.hello_world_soap_http.types.BareDocumentResponse;
>> import org.apache.hello_world_soap_http.types.GreetMeLaterResponse;
>> import org.apache.hello_world_soap_http.types.GreetMeResponse;
>> -
>> import org.junit.BeforeClass;
>> import org.junit.Test;
>>
>> @@ -1057,4 +1060,19 @@ public class ClientServerTest extends Ab
>> assertEquals("Hello World", resp);
>> }
>>
>> + @Test
>> + public void testEchoProviderAsync() throws Exception {
>> + String requestString = "<echo/>";
>> + Service service = Service.create(serviceName);
>> + service.addPort(fakePortName, javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
>> + "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider");
>> + Dispatch<StreamSource> dispatcher = service.createDispatch(fakePortName,
>> + StreamSource.class,
>> + Service.Mode.PAYLOAD);
>> +
>> + StreamSource request = new StreamSource(new ByteArrayInputStream(requestString.getBytes()));
>> + StreamSource response = dispatcher.invoke(request);
>> +
>> + assertEquals(requestString, StaxUtils.toString(response));
>> + }
>> }
>>
>> Modified: cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
>> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java?rev=1560703&r1=1560702&r2=1560703&view=diff
>> ==============================================================================
>> --- cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java (original)
>> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java Thu Jan 23 14:53:47 2014
>> @@ -25,8 +25,14 @@ import java.util.List;
>> import java.util.concurrent.Future;
>>
>> import javax.jws.WebService;
>> +import javax.xml.transform.Source;
>> +import javax.xml.transform.stream.StreamSource;
>> import javax.xml.ws.AsyncHandler;
>> import javax.xml.ws.Endpoint;
>> +import javax.xml.ws.Provider;
>> +import javax.xml.ws.Service;
>> +import javax.xml.ws.ServiceMode;
>> +import javax.xml.ws.WebServiceProvider;
>>
>> import org.apache.cxf.annotations.UseAsyncMethod;
>> import org.apache.cxf.interceptor.URIMappingInterceptor;
>> @@ -60,6 +66,10 @@ public class Server extends AbstractBusT
>> address = "http://localhost:" + PORT + "/SoapContext/AsyncSoapPort";
>> eps.add(Endpoint.publish(address, implementor));
>>
>> + implementor = new AsyncEchoProvider();
>> + address = "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider";
>> + eps.add(Endpoint.publish(address, implementor));
>> +
>> implementor = new GreeterImplMultiPort();
>> address = "http://localhost:" + PORT + "/MultiPort/GreeterPort";
>> eps.add(Endpoint.publish(address, implementor));
>> @@ -146,6 +156,33 @@ public class Server extends AbstractBusT
>> }
>> }
>>
>> + @WebServiceProvider
>> + @ServiceMode(value = Service.Mode.PAYLOAD)
>> + public class AsyncEchoProvider implements Provider<StreamSource> {
>> +
>> + @Override
>> + @UseAsyncMethod
>> + public StreamSource invoke(StreamSource request) {
>> + throw new RuntimeException("Should be async");
>> + }
>> +
>> + public Future<?> invokeAsync(final StreamSource s, final AsyncHandler<Source> asyncHandler) {
>> + final ServerAsyncResponse<Source> r = new ServerAsyncResponse<Source>();
>> + new Thread() {
>> + public void run() {
>> + try {
>> + Thread.sleep(500);
>> + } catch (InterruptedException e) {
>> + // ignore
>> + }
>> + r.set(s);
>> + asyncHandler.handleResponse(r);
>> + }
>> + } .start();
>> + return r;
>> + }
>> + }
>> +
>> public static void main(String[] args) {
>> try {
>> Server s = new Server();
>>
>>
--
Alessio Soldano
Web Service Lead, JBoss
Re: svn commit: r1560703 - in /cxf/branches/2.7.x-fixes: api/src/main/java/org/apache/cxf/service/invoker/ rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/ systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
Posted by Daniel Kulp <dk...@apache.org>.
Andrei,
This changes a protected method on a Abstract class that I believe either the JBoss folks or TomEE folks are subclassing. That’s a concern to me as that would be a backwards compatible break.
On 2.7.x, can we update the new method to handle when serviceObjectClass is null and re-introduce the original method calling the new one with null?
Dan
On Jan 23, 2014, at 9:53 AM, ashakirin@apache.org wrote:
> Author: ashakirin
> Date: Thu Jan 23 14:53:47 2014
> New Revision: 1560703
>
> URL: http://svn.apache.org/r1560703
> Log:
> Backported [CXF-5512]: @UseAsyncMethod annotation doesn't work for classes implementing Provider<T>
>
> Modified:
> cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
> cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
> cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
>
> Modified: cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
> ==============================================================================
> --- cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java (original)
> +++ cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java Thu Jan 23 14:53:47 2014
> @@ -66,7 +66,7 @@ public abstract class AbstractInvoker im
> params = new MessageContentsList(o);
> }
>
> - m = adjustMethodAndParams(m, exchange, params);
> + m = adjustMethodAndParams(m, exchange, params, serviceObject.getClass());
>
> //Method m = (Method)bop.getOperationInfo().getProperty(Method.class.getName());
> m = matchMethod(m, serviceObject);
> @@ -80,7 +80,8 @@ public abstract class AbstractInvoker im
>
> protected Method adjustMethodAndParams(Method m,
> Exchange ex,
> - List<Object> params) {
> + List<Object> params,
> + Class<?> serviceObjectClass) {
> //nothing to do
> return m;
> }
>
> Modified: cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
> ==============================================================================
> --- cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java (original)
> +++ cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java Thu Jan 23 14:53:47 2014
> @@ -20,6 +20,8 @@
> package org.apache.cxf.jaxws;
>
> import java.lang.reflect.Method;
> +import java.lang.reflect.ParameterizedType;
> +import java.lang.reflect.Type;
> import java.util.ArrayList;
> import java.util.Collection;
> import java.util.HashMap;
> @@ -30,6 +32,7 @@ import java.util.concurrent.ExecutionExc
>
> import javax.activation.DataHandler;
> import javax.xml.ws.AsyncHandler;
> +import javax.xml.ws.Provider;
> import javax.xml.ws.Response;
> import javax.xml.ws.handler.MessageContext;
> import javax.xml.ws.handler.MessageContext.Scope;
> @@ -52,6 +55,7 @@ import org.apache.cxf.message.FaultMode;
> import org.apache.cxf.message.Message;
> import org.apache.cxf.message.MessageContentsList;
> import org.apache.cxf.message.MessageImpl;
> +import org.apache.cxf.service.factory.ServiceConstructionException;
> import org.apache.cxf.service.invoker.Factory;
> import org.apache.cxf.service.invoker.FactoryInvoker;
> import org.apache.cxf.service.invoker.SingletonFactory;
> @@ -77,18 +81,24 @@ public abstract class AbstractJAXWSMetho
> }
> return null;
> }
> - protected Method adjustMethodAndParams(Method m, Exchange ex, List<Object> params) {
> +
> + @Override
> + protected Method adjustMethodAndParams(Method mOriginal, Exchange ex, List<Object> params,
> + Class<?> serviceObjectClass) {
> + // If class implements Provider<T> interface, use overriden method from service object class
> + // to check UseAsyncMethod annotation
> + Method mso = getProviderServiceObjectMethod(mOriginal, serviceObjectClass);
>
> - UseAsyncMethod uam = m.getAnnotation(UseAsyncMethod.class);
> + UseAsyncMethod uam = mso.getAnnotation(UseAsyncMethod.class);
> if (uam != null) {
> BindingOperationInfo bop = ex.getBindingOperationInfo();
> Method ret = bop.getProperty(ASYNC_METHOD, Method.class);
> if (ret == null) {
> - Class<?> ptypes[] = new Class<?>[m.getParameterTypes().length + 1];
> - System.arraycopy(m.getParameterTypes(), 0, ptypes, 0, m.getParameterTypes().length);
> - ptypes[m.getParameterTypes().length] = AsyncHandler.class;
> + Class<?> ptypes[] = new Class<?>[mso.getParameterTypes().length + 1];
> + System.arraycopy(mso.getParameterTypes(), 0, ptypes, 0, mso.getParameterTypes().length);
> + ptypes[mso.getParameterTypes().length] = AsyncHandler.class;
> try {
> - ret = m.getDeclaringClass().getMethod(m.getName() + "Async", ptypes);
> + ret = mso.getDeclaringClass().getMethod(mso.getName() + "Async", ptypes);
> bop.setProperty(ASYNC_METHOD, ret);
> } catch (Throwable t) {
> //ignore
> @@ -115,9 +125,52 @@ public abstract class AbstractJAXWSMetho
> }
> }
> }
> - return m;
> + return mOriginal;
> }
>
> + private Method getProviderServiceObjectMethod(Method m, Class<?> serviceObjectClass) {
> + if (!Provider.class.isAssignableFrom(serviceObjectClass)) {
> + return m;
> + }
> + Class<?> currentSvcClass = serviceObjectClass;
> + Class<?> genericType = null;
> +
> + while (currentSvcClass != null) {
> + genericType = getProviderGenericType(currentSvcClass);
> + if (genericType != null) {
> + break;
> + }
> + // Check superclass until top
> + currentSvcClass = currentSvcClass.getSuperclass();
> + }
> + // Should never happens
> + if (genericType == null) {
> + return m;
> + }
> + try {
> + return serviceObjectClass.getMethod("invoke", genericType);
> + } catch (Exception e) {
> + throw new ServiceConstructionException(e);
> + }
> + }
> +
> + private Class<?> getProviderGenericType(Class<?> svcClass) {
> + Type[] interfaces = svcClass.getGenericInterfaces();
> + for (Type interfaceType : interfaces) {
> + if (interfaceType instanceof ParameterizedType) {
> + ParameterizedType paramInterface = (ParameterizedType)interfaceType;
> + if (!paramInterface.getRawType().equals(Provider.class)) {
> + continue;
> + }
> + Type[] typeArgs = paramInterface.getActualTypeArguments();
> + if (typeArgs.length > 0) {
> + return (Class<?>)typeArgs[0];
> + }
> + }
> + }
> + return null;
> + }
> +
> class JaxwsServerHandler implements AsyncHandler<Object> {
> Response<Object> r;
> Continuation continuation;
>
> Modified: cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java?rev=1560703&r1=1560702&r2=1560703&view=diff
> ==============================================================================
> --- cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java (original)
> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java Thu Jan 23 14:53:47 2014
> @@ -19,6 +19,7 @@
>
> package org.apache.cxf.systest.jaxws;
>
> +import java.io.ByteArrayInputStream;
> import java.io.InputStream;
> import java.lang.reflect.InvocationHandler;
> import java.lang.reflect.Method;
> @@ -41,8 +42,10 @@ import java.util.logging.Logger;
> import java.util.zip.GZIPInputStream;
>
> import javax.xml.namespace.QName;
> +import javax.xml.transform.stream.StreamSource;
> import javax.xml.ws.AsyncHandler;
> import javax.xml.ws.BindingProvider;
> +import javax.xml.ws.Dispatch;
> import javax.xml.ws.Endpoint;
> import javax.xml.ws.Response;
> import javax.xml.ws.Service;
> @@ -63,6 +66,7 @@ import org.apache.cxf.frontend.ClientPro
> import org.apache.cxf.helpers.XMLUtils;
> import org.apache.cxf.helpers.XPathUtils;
> import org.apache.cxf.message.Message;
> +import org.apache.cxf.staxutils.StaxUtils;
> import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> import org.apache.cxf.transport.http.HTTPConduit;
> import org.apache.hello_world_soap_http.BadRecordLitFault;
> @@ -76,7 +80,6 @@ import org.apache.hello_world_soap_http.
> import org.apache.hello_world_soap_http.types.BareDocumentResponse;
> import org.apache.hello_world_soap_http.types.GreetMeLaterResponse;
> import org.apache.hello_world_soap_http.types.GreetMeResponse;
> -
> import org.junit.BeforeClass;
> import org.junit.Test;
>
> @@ -1057,4 +1060,19 @@ public class ClientServerTest extends Ab
> assertEquals("Hello World", resp);
> }
>
> + @Test
> + public void testEchoProviderAsync() throws Exception {
> + String requestString = "<echo/>";
> + Service service = Service.create(serviceName);
> + service.addPort(fakePortName, javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
> + "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider");
> + Dispatch<StreamSource> dispatcher = service.createDispatch(fakePortName,
> + StreamSource.class,
> + Service.Mode.PAYLOAD);
> +
> + StreamSource request = new StreamSource(new ByteArrayInputStream(requestString.getBytes()));
> + StreamSource response = dispatcher.invoke(request);
> +
> + assertEquals(requestString, StaxUtils.toString(response));
> + }
> }
>
> Modified: cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
> URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java?rev=1560703&r1=1560702&r2=1560703&view=diff
> ==============================================================================
> --- cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java (original)
> +++ cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java Thu Jan 23 14:53:47 2014
> @@ -25,8 +25,14 @@ import java.util.List;
> import java.util.concurrent.Future;
>
> import javax.jws.WebService;
> +import javax.xml.transform.Source;
> +import javax.xml.transform.stream.StreamSource;
> import javax.xml.ws.AsyncHandler;
> import javax.xml.ws.Endpoint;
> +import javax.xml.ws.Provider;
> +import javax.xml.ws.Service;
> +import javax.xml.ws.ServiceMode;
> +import javax.xml.ws.WebServiceProvider;
>
> import org.apache.cxf.annotations.UseAsyncMethod;
> import org.apache.cxf.interceptor.URIMappingInterceptor;
> @@ -60,6 +66,10 @@ public class Server extends AbstractBusT
> address = "http://localhost:" + PORT + "/SoapContext/AsyncSoapPort";
> eps.add(Endpoint.publish(address, implementor));
>
> + implementor = new AsyncEchoProvider();
> + address = "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider";
> + eps.add(Endpoint.publish(address, implementor));
> +
> implementor = new GreeterImplMultiPort();
> address = "http://localhost:" + PORT + "/MultiPort/GreeterPort";
> eps.add(Endpoint.publish(address, implementor));
> @@ -146,6 +156,33 @@ public class Server extends AbstractBusT
> }
> }
>
> + @WebServiceProvider
> + @ServiceMode(value = Service.Mode.PAYLOAD)
> + public class AsyncEchoProvider implements Provider<StreamSource> {
> +
> + @Override
> + @UseAsyncMethod
> + public StreamSource invoke(StreamSource request) {
> + throw new RuntimeException("Should be async");
> + }
> +
> + public Future<?> invokeAsync(final StreamSource s, final AsyncHandler<Source> asyncHandler) {
> + final ServerAsyncResponse<Source> r = new ServerAsyncResponse<Source>();
> + new Thread() {
> + public void run() {
> + try {
> + Thread.sleep(500);
> + } catch (InterruptedException e) {
> + // ignore
> + }
> + r.set(s);
> + asyncHandler.handleResponse(r);
> + }
> + } .start();
> + return r;
> + }
> + }
> +
> public static void main(String[] args) {
> try {
> Server s = new Server();
>
>
--
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com