[weld-dev] @Resource annotation handling by Weld vs Servlet container
Jan Bartel
janb at intalio.com
Sun Apr 12 20:13:05 EDT 2015
Hi Jozef,
Thanks for the info, a couple of followup questions inline ...
> to briefly explain the current integration: Handling or @Resource injection
> is not handled by Weld core itself. It is abstracted using the following
> SPI:
> http://docs.jboss.org/weld/javadoc/2.2/weld-spi/org/jboss/weld/injection/spi/ResourceInjectionServices.html
> Weld Servlet provides a default implementation of this SPI. An application,
> Servlet runtime or a library may provide an alternative implementation of
> the given service and take over resource lookups.
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?
> As for integration with Jetty, Weld provides a decorator that performs CDI
> and resource injection for Servlets, Filters and listeners. We can change
> that for Weld to only provide CDI injection
> (https://issues.jboss.org/browse/WELD-1919).
Looks like the decorator will only call inject anyway - in my tests I
haven't seen it call any PostConstruct or PreDestroy methods (on
servlet/filter/listeners at least).
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 ...
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 at intalio.com>
www.webtide.com
'Expert Jetty/CometD developer,production,operations advice'
More information about the weld-dev
mailing list