On 04/14/2015 07:17 AM, Jan Bartel wrote: > Hi Jozef, > >>>> Looking at the WeldServletLifecyle class on line 124, it will always >>>> provide an implementation of the ResourceInjectionServices (an >>>> instance of ServletResourceInjectionServices). If we were to provide >>>> our own implementation of ResourceInjectionServices, how would we >>>> override that one? Is there a way to get a hold of the Deployment and >>>> thus the BeanDeploymentArchives so we could set our own implementation >>>> up? Ideally we'd like a pure CDI api way of interacting with weld, but >>>> maybe that's not possible in this case? >>> You need to interact with Weld APIs to do this. A service can be overridden >>> using ServiceLoader mechanism. See >>> http://docs.jboss.org/weld/reference/2.2.10.Final/en-US/html/ri-spi.html#_registering_services >>> for details. >> Ok, great, I'll give this a go and report back. > I've implemented the service for the ResourceInjectionServices (for > now each method simply does a println), and it looks like weld is > seeing it: > > Apr 14, 2015 11:40:34 AM org.jboss.weld.bootstrap.AdditionalServiceLoader put > DEBUG: Installing additional service > org.jboss.weld.injection.spi.ResourceInjectionServices (class > org.eclipse.jetty.cdi.servlet.ResourceInjectionServices) > Weld ResourceInjectionServices jetty constructor called > > However, it does not appear to be being used, as I see no output from > my service, but still get the following error: > > java.lang.RuntimeException: Error looking up maxAmount in JNDI > at > org.jboss.weld.injection.spi.helpers.AbstractResourceServices.resolveResource(AbstractResourceServices.java:50) > at > org.jboss.weld.injection.spi.helpers.AbstractResourceServices$1.createResource(AbstractResourceServices.java:121) > at > org.jboss.weld.injection.AbstractResourceInjection.getResourceReference(AbstractResourceInjection.java:44) > at > org.jboss.weld.injection.AbstractResourceInjection.injectResourceReference(AbstractResourceInjection.java:53) > at org.jboss.weld.util.Beans.injectEEFields(Beans.java:344) > at > org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:69) > at > org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48) > at > org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72) > at > org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:121) > at > org.jboss.weld.environment.servlet.inject.AbstractInjector.inject(AbstractInjector.java:55) > at > org.jboss.weld.environment.jetty.JettyWeldInjector.inject(JettyWeldInjector.java:15) > at > org.jboss.weld.environment.jetty.WeldDecorator.decorate(WeldDecorator.java:105) > at > org.eclipse.jetty.util.DecoratedObjectFactory.decorate(DecoratedObjectFactory.java:77) > at > org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:335) > at > org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349) > > Any hints? Actually I somehow missed the fact the ResourceInjectionServices are per-module instead of per-deployment type of Service. As a result, it is not possible to override it using AdditionalServiceLoader. See my other e-mail for details. Sorry about that. > > thanks, > Jan > >> >>>> Alternatively, instead of Weld >>>>> hooking into lifecycle of Jetty-managed components, Jetty could use CDI >>>>> APIs >>>>> to perform CDI injection on instances it manages. >>>>> >>>> Yes, potentially we could do that, although we'd probably need your >>>> guidance on the best way to do that. Can @Resource be used by pojo >>>> beans or only by servlet artifacts (servlet/filter/listeners)? If the >>>> latter, then I'm fine for Jetty to do all the handling of @Resource. >>>> If not, then it probably makes sense for weld to handle it, and we'd >>>> need a way to disable Jetty's implementation if weld is present in a >>>> webapp ... >>> I think the best approach would be to modify the integrating decorator to >>> only provide CDI injection to Jetty-managed instances. I have implemented it >>> here: >>> https://github.com/weld/core/commit/f7420e34355c5c82ef516713c65fc6cd750fb651 >> So if jetty is handling @Resource (handling making the jndi entries >> and injecting the fields/methods) for servlets/filters/listeners, what >> will happen if someone declares this in eg a servlet: >> >> public class MyServlet extends HttpServlet >> { >> >> @Producer @Resource (name="foo") >> @MyDb >> private DataSource db; >> } >> >> Will weld still inspect this class and find the producer and make it >> available for injection in other code? >> >> cheers >> Jan >> >>>> cheers >>>> Jan >>>> >>>>> Additional comments inline: >>>>> >>>>> >>>>> On 04/10/2015 02:00 AM, Jan Bartel wrote: >>>>>> Hi Weld developers, >>>>>> >>>>>> The Jetty project is looking at how we can do a tighter integration >>>>>> with Weld, also with a view to discussions in the Servlet Spec 4 >>>>>> committee to alleviate the necessity for CDI implementations to >>>>>> maintain jetty-specific initialisation code. >>>>>> >>>>>> During investigations, I noticed that we seem to have a conflict in >>>>>> the handling of a few annotations for classes that are managed by the >>>>>> servlet container (ie servlets, filters, listeners etc): >>>>>> >>>>>> @Resource >>>>>> @PostConstruct >>>>>> @PreDestroy >>>>>> >>>>>> As Jetty puts a servlet/filter/listener into service, we introspect >>>>>> the class and find the above annotations and process them. It seems >>>>>> that Weld does too, as I see the following failure for this code >>>>>> snippet: >>>>>> >>>>>> public class TestListener implements ServletContextListener >>>>>> { >>>>>> @Resource(mappedName="maxAmount") >>>>>> private Double maxAmount; >>>>>> } >>>>>> >>>>>> >>>>>> javax.naming.NameNotFoundException; remaining name 'maxAmount' >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:429) >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:533) >>>>>> at javax.naming.InitialContext.lookup(InitialContext.java:411) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.spi.helpers.AbstractResourceServices.resolveResource(AbstractResourceServices.java:48) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.spi.helpers.AbstractResourceServices$1.createResource(AbstractResourceServices.java:121) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.AbstractResourceInjection.getResourceReference(AbstractResourceInjection.java:44) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.AbstractResourceInjection.injectResourceReference(AbstractResourceInjection.java:53) >>>>>> at org.jboss.weld.util.Beans.injectEEFields(Beans.java:344) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:69) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72) >>>>>> at >>>>>> >>>>>> org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:121) >>>>>> at >>>>>> >>>>>> org.jboss.weld.environment.servlet.inject.AbstractInjector.inject(AbstractInjector.java:55) >>>>>> at >>>>>> >>>>>> org.jboss.weld.environment.jetty.JettyWeldInjector.inject(JettyWeldInjector.java:15) >>>>>> at >>>>>> >>>>>> org.jboss.weld.environment.jetty.WeldDecorator.decorate(WeldDecorator.java:105) >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.util.DecoratedObjectFactory.decorate(DecoratedObjectFactory.java:77) >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:335) >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349) >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342) >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:743) >>>>>> at >>>>>> >>>>>> org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:257) >>>>>> at >>>>>> org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505) >>>>>> >>>>>> >>>>>> Googling around, it is not clear to me exactly which of the Common >>>>>> Annotations (JSR250) that Weld supports and I'd appreciate some input >>>>>> from the Weld devs in order for Jetty to work out how best to move >>>>>> forward with Weld integration. >>>>>> >>>>>> In particular, I'd appreciate some clear feedback on which of the >>>>>> following @Resource annotation usages will be handled by Weld: >>>>>> >>>>>> @Resource on a class >>>>>> @Resource on a field >>>>>> @Resource on a method >>>>>> @Resource annotations without an accompanying @Producer annotation >>>>> @Resource on a field (with or without @Producer), @Resource on a method, >>>>> @PostConstruct and @PreDestroy are handled by Weld on a managed instance >>>>> (generally). >>>>>> >>>>>> Secondly, as can be seen from the stacktrace above, Weld is failing to >>>>>> find the matching JNDI entry for an @Resource annotation. This is >>>>>> because Weld appears not to be looking in "java:comp/env" namespace, >>>>>> although IIRC that is mandated by the JavaEE spec for EE managed >>>>>> classes (servlets/filters/listeners etc). So if Jetty delegates >>>>>> handling of some/all processing of @Resource, how do we ensure that >>>>>> Weld will be able to find the right JNDI entry? >>>>> This might be a bug in weld-servlet's ResourceInjectionServices >>>>> implementation. Can you file an issue at >>>>> https://issues.jboss.org/browse/WELD ? >>>>> >>>>>> thanks for your time, >>>>>> Jan >>>>> >>>> >> >> >> -- >> Jan Bartel <[email protected]> >> www.webtide.com >> 'Expert Jetty/CometD developer,production,operations advice' > >
_______________________________________________ weld-dev mailing list [email protected] https://lists.jboss.org/mailman/listinfo/weld-dev
