Hi Josef,
The EE spec group were having a very long discussion about CDI and
annotation handling (thread ref:
)
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 <jharting(a)redhat.com> 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#...
>>> 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 <janb(a)intalio.com>
>>
www.webtide.com
>> 'Expert Jetty/CometD developer,production,operations advice'
>
>
>