-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DecoratingListener raises a NullPointerException #5162
Comments
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. |
So there is definitely at least something wrong with both sets of embedded documentation as 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 ... |
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 |
Can you explain this in a bit more detail? |
I should have written: “one of the things I am interested in is to have a container react to AFAIU, this is a job for CDI together with some TransactionManager (which registers CDI interceptors to act upon |
@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: context.addEventListener(new org.jboss.weld.environment.servlet.Listener()); 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: context.addEventListener(new org.eclipse.jetty.webapp.DecoratingListener(context));
context.addEventListener(new org.jboss.weld.environment.servlet.Listener()); 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 new CdiServletContainerInitializer().onStartup(Collections.emptySet(), context.getServletContext());
context.addEventListener(new org.jboss.weld.environment.servlet.Listener()); 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? |
Looking for better ways to start CDI embedded.... ultimately it is best to just use the If you are not using a real webapp, ie using private static class SciStarter extends AbstractLifeCycle implements ServletContextHandler.ServletContainerInitializerCaller
{
private final ServletContext _context;
private final List<ServletContainerInitializer> _initializers = new ArrayList<>();
private SciStarter(ServletContext context)
{
_context = context;
}
public void add(ServletContainerInitializer initializer)
{
_initializers.add(initializer);
}
@Override
protected void doStart() throws Exception
{
for (ServletContainerInitializer sci : _initializers)
sci.onStartup(Collections.emptySet(), _context);
}
} Your startup code then can look like: Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
server.setHandler(context);
SciStarter sciStarter = new SciStarter(context.getServletContext());
context.addBean(sciStarter);
context.setInitParameter(org.eclipse.jetty.cdi.CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE, org.eclipse.jetty.cdi.CdiDecoratingListener.MODE);
sciStarter.add(new org.eclipse.jetty.cdi.CdiServletContainerInitializer());
sciStarter.add(new org.jboss.weld.environment.servlet.EnhancedListener()); So that could be simplified a little (eg we should provide a utility Now the strange thing is that because you are using a |
I was able to not use jetty-cdi at all, and rely solely on the weld-servlet-core artifact. This works for package org.eclipse.jetty.demo.embedded;
import org.eclipse.jetty.demo.logging.Logging;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.JavaUtilLog;
import org.eclipse.jetty.util.log.Log;
import org.jboss.weld.environment.servlet.EnhancedListener;
public class EmbeddedDemo
{
public static void main(String[] args) throws Exception
{
Logging.config();
Log.setLog(new JavaUtilLog());
Server server = new Server(8099);
final ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.setContextPath("/");
contextHandler.addServlet(HelloServlet.class, "/hi/*");
contextHandler.addServlet(GreetingsServlet.class, "/greetings/*");
contextHandler.addBean(new WeldInitializer(contextHandler));
server.setHandler(contextHandler);
try
{
server.start();
HttpClient.GET(server.getURI().resolve("/hi/"));
HttpClient.GET(server.getURI().resolve("/greetings/"));
}
finally
{
LifeCycle.stop(server);
}
}
public static class WeldInitializer extends AbstractLifeCycle
{
private final ServletContextHandler contextHandler;
public WeldInitializer(ServletContextHandler contextHandler)
{
this.contextHandler = contextHandler;
}
@Override
protected void doStart() throws Exception
{
EnhancedListener enhancedListener = new EnhancedListener();
enhancedListener.onStartup(null, contextHandler.getServletContext());
super.doStart();
}
}
} |
This works too. package org.eclipse.jetty.demo.embedded;
import org.eclipse.jetty.demo.logging.Logging;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.JavaUtilLog;
import org.eclipse.jetty.util.log.Log;
public class EmbeddedListenerDemo
{
public static void main(String[] args) throws Exception
{
Logging.config();
Log.setLog(new JavaUtilLog());
Server server = new Server(8099);
final ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.setContextPath("/");
contextHandler.addServlet(HelloServlet.class, "/hi/*");
contextHandler.addServlet(GreetingsServlet.class, "/greetings/*");
contextHandler.addEventListener(new org.jboss.weld.environment.servlet.Listener());
server.setHandler(contextHandler);
try
{
server.start();
HttpClient.GET(server.getURI().resolve("/hi/"));
HttpClient.GET(server.getURI().resolve("/greetings/"));
}
finally
{
LifeCycle.stop(server);
}
}
} |
@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. |
Clean up CDI integration and documentation to better support embedded usage. + made listener public + added utility class for SCIs
Clean up CDI integration and documentation to better support embedded usage. + moved EmbeddedWeldTest to jetty-embedded
Moved tests to jetty-cdi to avoid consequences to other tests in embedded
* Issue #5162 CDI embedded integration improvements Clean up CDI integration and documentation to better support embedded usage. + made listener public + added utility class for SCIs * Issue #5162 CDI embedded integration improvements Clean up CDI integration and documentation to better support embedded usage. + moved EmbeddedWeldTest to jetty-embedded * fix javadoc Signed-off-by: Greg Wilkins <[email protected]> * Issue #5162 CDI embedded integration improvements ventilated text * fix test pom Signed-off-by: Greg Wilkins <[email protected]> * Fixed javadoc * Fixed javadoc * Issue #5162 CDI embedded integration improvements Moved tests to jetty-cdi to avoid consequences to other tests in embedded * trailing new line Signed-off-by: Greg Wilkins <[email protected]> * updates from review Signed-off-by: Greg Wilkins <[email protected]> * Feedback from review
Thanks for your very prompt reaction. I see that the related PR (including changes to the documentation, if I understand correctly) has now been merged into 9.4.x. Any idea when this will be consumable through Maven central and when the documentation changes will be visible online (the “current” documentation is at version 9.4.31.v20200723)? Or can I see it somewhere already? |
I saw that that PR has been merged to 9.4.x, but my question was about concrete availability as a consumable Maven artifact. Is there some documentation about the release policy? I’d like to know if I can expect the patch to become available in the nearby future. (I am not requesting any specific, precise date; I know that this is not how things work.) The last 9.x release is now relatively long past, compared to the usual schedule (usually a release every month or more); does it mean that the next one is coming soon, or that attention is now shifting to the 10.x branch? Relatedly, are there some snapshots available, in the meantime? Sorry if I missed something obvious, but I couldn’t find anything about the release policy on the website or in the documentation. |
nightly snapshots are available on oss.sonatype.org URL - https://oss.sonatype.org/content/repositories/jetty-snapshots/ We are working towards a 9.4.32 release, which will contain this fix. |
Thanks. Please consider documenting this “nightly snapshot” URL, perhaps in the about section. (In retrospect, I admit I should have thought about searching there for snapshots, but better make it explicit as I suppose others could find it useful.) |
We generally encourage people to build and test from the git repository. |
I just built the doc from source. I am able to make injection work by following the new instructions. Great! (I use the jetty-snapshot, contrary to instructions here above, because I did not manage to compile jetty from sources yet, I hope that is okay.) I have however a few questions because I am not sure I am setting things up as I should. Perhaps the doc could be improved so as to remove any doubt from the reader?
The log is the following when my application starts.
|
Perhaps interestingly, the illegal reflective access happens in this class, which seems to mention (if I understand it correctly) that this is because “the integrator does not fully implement ProxyServices”. Is this something that jetty can solve, or due to me not having followed the instructions correctly? |
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.
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 section18.3.2.4. Binding BeanManager to Jetty JNDI
(or others) in supplement to18.3.2.5. Embedded Jetty
or if18.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.)
Possibly related
#4064 #3804 #4121
The text was updated successfully, but these errors were encountered: