tomee specific I guess but just a general case of cdi injections in jaxws endpoints, btw i have to cleanup this commit, will try in 1h Romain Manni-Bucau Twitter: @rmannibucau Blog: http://rmannibucau.wordpress.com/ LinkedIn: http://fr.linkedin.com/in/rmannibucau Github: https://github.com/rmannibucau
2014/1/12 Jacek Laskowski <[email protected]>: > 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
