Description
Jetty version
9.4.31.v20200723 (Maven)
Java version
OpenJDK 11
OS type/version
Debian stable
Description
The sample code from the Weld embedded section in the Jetty Reference raises a NullPointerException.
Here is the stack trace.
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at org.eclipse.jetty.servlet.DecoratingListener.<init>(DecoratingListener.java:67)
at org.eclipse.jetty.webapp.DecoratingListener.<init>(DecoratingListener.java:49)
at org.eclipse.jetty.webapp.DecoratingListener.<init>(DecoratingListener.java:39)
at org.eclipse.jetty.webapp.DecoratingListener.<init>(DecoratingListener.java:34)
at io.github.oliviercailloux.jetty.App.main(App.java:64)
This could be a usage problem. It is unclear to me, reading the documentation, if I have to apply anything from the section “Weld Setup” (in the same page), when running in embedded mode (and if so, what), or if the Weld embedded section is to be applied to the exclusion of the other part. If I have to include the cdi-decorate module, how can I do this with Maven? In any case, the problem also happens with org.eclipse.jetty:jetty-cdi
included in the project dependencies.
The Weld documentation gives almost the same instructions, but not exactly: one line of code, context.addEventListener(new Listener());
has been added. Which version is correct? And, similarly, I ignore whether I am supposed to apply section 18.3.2.4. Binding BeanManager to Jetty JNDI
(or others) in supplement to 18.3.2.5. Embedded Jetty
or if 18.3.2.5. Embedded Jetty
is sufficient.
(I also want to use Jersey, which further complicates the matter, but I suppose that this issue is unrelated as the bug happens with a sample code that does not involve Jersey.)
Activity
gregw commentedon Aug 17, 2020
Sorry for the confusion. We are always a bit confused with CDI as well.... the problem being that there is no standard nor agreement between the CDI implementations as to how they should integrate with a servlet container, further complicated by the historic usage of jetty APIs for integration that were not meant to be public and have now changed.
We've tried to push the implementations to a single obvious way to integrate, but failed in that approach. Hence the hodge podge of different mechanisms that are very version dependent.
I'll check our examples and see if we can update our documentation and/or fix anything for the weld integration.
Jersey should not be anywhere as near as complex, as it does not need to plug into the containers decoration mechanism.
gregw commentedon Aug 17, 2020
So there is definitely at least something wrong with both sets of embedded documentation as
DecoratingListener
will not work with a default constructor unless called from the scope of a context listener or similar. Thus in the embedded examples, at the very least the constructor that takes a context needs to be used. It may also be the case thatCdiDecoratingListener
should be used.This may take me a little while to page all this back into my brain and work out exactly the best way to fix the documentation, but feel free to try either/both of the above suggestions. Standby ...
oliviercailloux commentedon Aug 18, 2020
Thanks for investigating!
I do not understand this sentence. I thought I’d better first make sure Jetty and Weld work together, before trying to tackle the (or what I thought to be the) additional difficulty of making Jersey also work with Jetty and Weld (meaning, make my Jersey-operated Jax-RS servlet handle dependency injection).
Does your sentence suggest that it is in fact easier to set up Jersey for working with Weld, and that I’d better not insist in making Weld behave well with Jetty (or conversely)?
Specifically, one of the things I am interested in is to have the container react to
@Transactional
annotations (using JPA and a JTA transactional manager).joakime commentedon Aug 18, 2020
Can you explain this in a bit more detail?
Which container?
Jetty (which isn't involved in DataSource behaviors)?
Jersey (which is also a container)?
Weld (which is also a container)?
Or something else?
oliviercailloux commentedon Aug 19, 2020
I should have written: “one of the things I am interested in is to have a container react to
@Transactional
annotations (using JPA and a JTA transactional manager).” (I also would like to use the other CDI basic stuff such as@Inject
, of course.)AFAIU, this is a job for CDI together with some TransactionManager (which registers CDI interceptors to act upon
@Transactional
). See this post for example. Hence, my desire to make Jetty interact with Weld properly. Tell me if I am mistaken.gregw commentedon Aug 19, 2020
@oliviercailloux I've now found a few niggling problems with the various ways that jetty can integrate with Weld when used in an embedded style, specially following our examples. So I will be doing a PR to fix them up.... mostly the issue is that all the goodness we've written for CDI integration is within a ServletContainerInitializer that may not be triggered by embedded usage.
For now you should be able to write just:
which should result in the message:
which shows that Welds built in integration is working for Filters and Servlets. If you want Listeners you need to use:
which when run will produce the message:
that at least confirms the integration is done.
Actually you can do a little hack to avoid the deprecated warning, by instead invoking the SCI directly
which then reports:
We will clean this up in the next release. @janbartel what is the status of calling SCIs from embedded server usage? Should that have been working anyway? Would it just be a mater of making sure jetty-cdi is on the classpath? That doesn't appear to work for me?
gregw commentedon Aug 19, 2020
Looking for better ways to start CDI embedded.... ultimately it is best to just use the
ServletContainerInitializers
.If you are not using a real webapp, ie using
ServletContextHandler
instead of aWebppContext
, then you can achieve this by clearing a little class like:Your startup code then can look like:
So that could be simplified a little (eg we should provide a utility
SciStarter
) , but it's not too ugly.Now the strange thing is that because you are using a
WebappContext
(or at least the documentation suggest that you should), then the SCI's should have already been found for you? Hmm maybe we need to tell it to search for them??? stand by...joakime commentedon Aug 19, 2020
I was able to not use jetty-cdi at all, and rely solely on the weld-servlet-core artifact.
This works for
ServletContextHandler
just fine.And isn't appropriate when using
WebAppContext
.joakime commentedon Aug 19, 2020
This works too.
For both
ServletContextHandler
andWebAppContext
usages.gregw commentedon Aug 19, 2020
@joakime that method only partially works. It uses the Weld integration which will give you the log message:
ie Listener injection is not supported.
This way will also not work with jetty-10.
Issue #5162 CDI embedded integration improvements
Issue #5162 CDI embedded integration improvements
Issue #5162 CDI embedded integration improvements
12 remaining items