Hi Jan,
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/...
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.
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). Alternatively, instead of
Weld hooking into lifecycle of Jetty-managed components, Jetty could use
CDI APIs to perform CDI injection on instances it manages.
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