Hi Josef, The EE spec group were having a very long discussion about CDI and annotation handling (thread ref: https://java.net/projects/javaee-spec/lists/users/archive/2015-02/message/54) wrt updating EE7 and creating EE8. Do you know where that landed? Is there any clarification on whether the servlet container or CDI impl is supposed to be interpreting the @Resource annotations?
cheers Jan On 14 April 2015 at 23:19, Jozef Hartinger <[email protected]> wrote: > > > 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' >> >> >> > -- Jan Bartel <[email protected]> www.webtide.com 'Expert assistance from the creators of Jetty and CometD' _______________________________________________ weld-dev mailing list [email protected] https://lists.jboss.org/mailman/listinfo/weld-dev
