Hi, Is the feature of "jaxws endpoints as cdi beans" something TomEE-specific or spec-compliant? What spec would that feature be described in?
Jacek On Sun, Jan 12, 2014 at 10:48 AM, <[email protected]> wrote: > Author: rmannibucau > Date: Sun Jan 12 09:48:00 2014 > New Revision: 1557507 > > URL: http://svn.apache.org/r1557507 > Log: > TOMEE-1105 jaxws endpoints as cdi beans > > Added: > > tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/CdiPojoTest.java > - copied, changed from r1556736, > tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/PojoWebServiceContextTest.java > Modified: > > tomee/tomee/trunk/server/openejb-cxf/src/main/java/org/apache/openejb/server/cxf/pojo/PojoEndpoint.java > > Modified: > tomee/tomee/trunk/server/openejb-cxf/src/main/java/org/apache/openejb/server/cxf/pojo/PojoEndpoint.java > URL: > http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf/src/main/java/org/apache/openejb/server/cxf/pojo/PojoEndpoint.java?rev=1557507&r1=1557506&r2=1557507&view=diff > ============================================================================== > --- > tomee/tomee/trunk/server/openejb-cxf/src/main/java/org/apache/openejb/server/cxf/pojo/PojoEndpoint.java > (original) > +++ > tomee/tomee/trunk/server/openejb-cxf/src/main/java/org/apache/openejb/server/cxf/pojo/PojoEndpoint.java > Sun Jan 12 09:48:00 2014 > @@ -29,12 +29,24 @@ import org.apache.cxf.transport.http.HTT > import org.apache.openejb.Injection; > import org.apache.openejb.InjectionProcessor; > import org.apache.openejb.assembler.classic.util.ServiceConfiguration; > +import org.apache.openejb.cdi.CdiAppContextsService; > import org.apache.openejb.core.webservices.JaxWsUtils; > import org.apache.openejb.core.webservices.PortData; > import org.apache.openejb.server.cxf.CxfEndpoint; > import org.apache.openejb.server.cxf.CxfServiceConfiguration; > import org.apache.openejb.server.cxf.JaxWsImplementorInfoImpl; > - > +import org.apache.openejb.util.LogCategory; > +import org.apache.openejb.util.Logger; > +import org.apache.webbeans.component.AbstractOwbBean; > +import org.apache.webbeans.config.WebBeansContext; > +import org.apache.webbeans.container.BeanManagerImpl; > +import org.apache.webbeans.context.creational.CreationalContextImpl; > +import org.apache.webbeans.util.WebBeansUtil; > + > +import javax.enterprise.context.Dependent; > +import javax.enterprise.inject.spi.Bean; > +import javax.enterprise.inject.spi.InjectionTarget; > +import javax.enterprise.inject.spi.Producer; > import javax.naming.Context; > import javax.xml.ws.WebServiceContext; > import javax.xml.ws.WebServiceException; > @@ -42,10 +54,12 @@ import java.lang.reflect.Type; > import java.util.Iterator; > import java.util.List; > import java.util.Map; > +import java.util.Set; > > import static org.apache.openejb.InjectionProcessor.unwrap; > > public class PojoEndpoint extends CxfEndpoint { > + private static final Logger LOGGER = Logger.getInstance(LogCategory.CXF, > PojoEndpoint.class); > private static final WebServiceContextResourceResolver > WEB_SERVICE_CONTEXT_RESOURCE_RESOLVER = new > WebServiceContextResourceResolver(); > > private final ResourceInjector injector; > @@ -53,7 +67,7 @@ public class PojoEndpoint extends CxfEnd > public PojoEndpoint(ClassLoader loader, Bus bus, PortData port, Context > context, Class<?> instance, > HTTPTransportFactory httpTransportFactory, > Map<String, Object> bindings, ServiceConfiguration > config) { > - super(bus, port, context, instance, httpTransportFactory, config); > + super(bus, port, context, instance, httpTransportFactory, config); > > String bindingURI = null; > if (port.getBindingID() != null) { > @@ -81,21 +95,67 @@ public class PojoEndpoint extends CxfEnd > } > } > > + ResourceInjector injector = null; > + > // instantiate and inject resources into service using the app > classloader to be sure to get the right InitialContext > + implementor = null; > + > final ClassLoader old = > Thread.currentThread().getContextClassLoader(); > Thread.currentThread().setContextClassLoader(loader); > try { > - final InjectionProcessor<Object> injectionProcessor = new > InjectionProcessor<Object>(instance, port.getInjections(), null, null, > unwrap(context), bindings); > - injectionProcessor.createInstance(); > - implementor = injectionProcessor.getInstance(); > - injector = injectCxfResources(implementor); > - injector.invokePostConstruct(); > + final WebBeansContext webBeansContext = > WebBeansContext.currentInstance(); > + final BeanManagerImpl bm = webBeansContext.getBeanManagerImpl(); > + if (bm.isInUse()) { // try cdi bean > + try { > + final Set<Bean<?>> beans = bm.getBeans(instance); > + final Bean<?> bean = bm.resolve(beans); > + CreationalContextImpl creationalContext = > bm.createCreationalContext(bean); > + if (bean != null) { > + Bean<?> oldBean = creationalContext.putBean(bean); > + try { > + if (AbstractOwbBean.class.isInstance(bean)) { > + final AbstractOwbBean<?> aob = > AbstractOwbBean.class.cast(bean); > + > + final Producer producer = aob.getProducer(); > + implementor = > producer.produce(creationalContext); > + if (producer instanceof InjectionTarget) { > + final InjectionTarget injectionTarget = > (InjectionTarget) producer; > + injectionTarget.inject(implementor, > creationalContext); > + injector = > injectCxfResources(implementor); // we need it before postconstruct > + > injectionTarget.postConstruct(implementor); > + } > + if (aob.getScope().equals(Dependent.class)) { > + creationalContext.addDependent(aob, > instance); > + } > + } > + } finally { > + creationalContext.putBean(oldBean); > + } > + } else { > + implementor = bm.getReference(bean, instance, > creationalContext); > + injector = injectCxfResources(implementor); > + } > + if (WebBeansUtil.isDependent(bean)) { // should be > isPseudoScope but should be ok for jaxws > + CdiAppContextsService.pushRequestReleasable(new > RealeaseCreationalContextRunnable(creationalContext)); > + } > + } catch (final Exception ie) { > + LOGGER.info("Can't use cdi to create " + instance + " > webservice: " + ie.getMessage()); > + } > + } > + if (implementor == null) { // old pojo style > + final InjectionProcessor<Object> injectionProcessor = new > InjectionProcessor<Object>(instance, port.getInjections(), null, null, > unwrap(context), bindings); > + injectionProcessor.createInstance(); > + implementor = injectionProcessor.getInstance(); > + injector = injectCxfResources(implementor); > + injector.invokePostConstruct(); > + } > } catch (final Exception e) { > throw new WebServiceException("Service resource injection > failed", e); > } finally { > Thread.currentThread().setContextClassLoader(old); > } > > + this.injector = injector; > service.setInvoker(new JAXWSMethodInvoker(implementor)); > } > > @@ -141,4 +201,17 @@ public class PojoEndpoint extends CxfEnd > // shutdown server > super.stop(); > } > + > + private static class RealeaseCreationalContextRunnable implements > Runnable { > + private final CreationalContextImpl<?> cc; > + > + public RealeaseCreationalContextRunnable(final > CreationalContextImpl<?> creationalContext) { > + this.cc = creationalContext; > + } > + > + @Override > + public void run() { > + cc.release(); > + } > + } > } > > Copied: > tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/CdiPojoTest.java > (from r1556736, > tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/PojoWebServiceContextTest.java) > URL: > http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/CdiPojoTest.java?p2=tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/CdiPojoTest.java&p1=tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/PojoWebServiceContextTest.java&r1=1556736&r2=1557507&rev=1557507&view=diff > ============================================================================== > --- > tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/PojoWebServiceContextTest.java > (original) > +++ > tomee/tomee/trunk/server/openejb-cxf/src/test/java/org/apache/openejb/server/cxf/CdiPojoTest.java > Sun Jan 12 09:48:00 2014 > @@ -18,6 +18,7 @@ package org.apache.openejb.server.cxf; > > import org.apache.openejb.jee.WebApp; > import org.apache.openejb.junit.ApplicationComposer; > +import org.apache.openejb.testing.Classes; > import org.apache.openejb.testing.EnableServices; > import org.apache.openejb.testing.Module; > import org.junit.Test; > @@ -25,22 +26,39 @@ import org.junit.runner.RunWith; > > import javax.annotation.PostConstruct; > import javax.annotation.Resource; > +import javax.inject.Inject; > import javax.jws.WebService; > +import javax.xml.namespace.QName; > +import javax.xml.ws.Service; > import javax.xml.ws.WebServiceContext; > > +import java.net.MalformedURLException; > +import java.net.URL; > + > +import static org.junit.Assert.assertEquals; > import static org.junit.Assert.assertTrue; > > @EnableServices("jax-ws") > @RunWith(ApplicationComposer.class) > -public class PojoWebServiceContextTest { > +public class CdiPojoTest { > @Module > + @Classes(value = { MyWebservice.class, ACdiTaste.class }, cdi = true) > public WebApp module() { > return new WebApp().contextRoot("/test").addServlet("ws", > MyWebservice.class.getName(), "/ws"); > } > > @Test > - public void checkInjection() { > - assertTrue(MyWebservice.ok); > + public void checkInjection() throws MalformedURLException { > + final MyWsApi api = Service.create(new > URL("http://localhost:4204/test/ws?wsdl"), > + new > QName("http://cxf.server.openejb.apache.org/", "MyWebserviceService")) > + .getPort(MyWsApi.class); > + assertEquals("ok", api.test()); > + } > + > + public static class ACdiTaste { > + public String ok() { > + return "ok"; > + } > } > > @WebService > @@ -50,19 +68,15 @@ public class PojoWebServiceContextTest { > > @WebService > public static class MyWebservice implements MyWsApi { > - private static boolean ok = false; > - > - @Resource > - private WebServiceContext ctx; > - > - @PostConstruct > - public void check() { > - ok = ctx != null; > - } > + @Inject > + private ACdiTaste cdi; > > @Override > public String test() { > - return "ok"; > + if (cdi == null) { > + return "cdi injection failed"; > + } > + return cdi.ok(); > } > } > } > > -- Jacek Laskowski Functional languages (Clojure), Java EE, and IBM WebSphere - http://blog.japila.pl "Never discourage anyone who continually makes progress, no matter how slow." Plato
