Re: Using Guice with embedded jetty 7.5.2

530 views
Skip to first unread message

Jared Bunting

unread,
Jun 27, 2012, 8:15:55 AM6/27/12
to google...@googlegroups.com
You don't seem to do anything with your injector. I'm doing something
similar for a couple of apps, but my approach would look more like this:

=== Launcher class:

public static void main(String[] args) throws Exception {
Injector injector = Guice.createInjector(
new MadServingModule(),
new MadMockModule(),
new MadTrackModule(),
new MadMiscModule());

ServletContextHandler servletContextHandler = new
ServletContextHandler();
servletContextHandler.addFilter(new
FilterHolder(injector.getInstance(GuiceFilter.class)), "/",
FilterMapping.ALL);

Server server = new Server(PORT_NUMBER);
server.setHandler(servletContextHandler);

// Init the application itself
MADServiceMgr.init();

// ### Launching the application...
server.start();
System.out.println(server.dump());
server.join();
}

The two main differences are that I am saving the injector after
creating it (otherwise, how would anything use it?) and that I allow the
injector to instantiate the GuiceFilter (thus giving the GuiceFilter
access to all of my Guice-configured servlets).

Hope that helps,
Jared

On Wed 27 Jun 2012 04:08:34 AM CDT, Maxim Veksler wrote:
>
> Hello,
>
> Our app launches from void main() with embedded Jetty.
> We try to keep it light weight, and don't have full WebAppContext,
> instead with start with HandlerCollection and simply map the servlets
> to paths.
>
> I would like to integrate Guice into the mix, I've
> followed http://code.google.com/p/google-guice/wiki/ServletModule and
> re-factored the
> code to replace Jetty mapping with guiced based approach. I'm not sure
> if my problem is with Jetty or Guice but after switch to Guice serve()
> mapping I can't seem to be able to have any GET requested to be
> redirected into the appropriate servlets, which makes Jetty always
> return a 404.
>
>
> My relevant code code snippets:
>
> === Launcher class:
>
> public static void main(String[] args) throws Exception {
> Guice.createInjector(
> new MadServingModule(),
> new MadMockModule(),
> new MadTrackModule(),
> new MadMiscModule());
>
> ServletContextHandler servletContextHandler = new
> ServletContextHandler();
> servletContextHandler.addFilter(new
> FilterHolder(GuiceFilter.class), "/", FilterMapping.ALL);
>
> Server server = new Server(PORT_NUMBER);
> server.setHandler(servletContextHandler);
>
> // Init the application itself
> MADServiceMgr.init();
>
> // ### Launching the application...
> server.start();
> System.out.println(server.dump());
> server.join();
> }
>
> === MadMiscModule class
>
> public class MadMiscModule extends ServletModule {
> @Override
> protected void configureServlets() {
> // ### STATUS ###
> serve("/status").with(StatusServlet.class);
>
> // ### STATIC STUFF ###
> serve("/crossdomain.xml").with(CrossdomainServlet.class);
> serve("/robots.txt").with(RobotsTxtServlet.class);
> }
> }
>
>
> I've verified that both GuiceFilter.init()
> and MadMiscModule.configureServlets() methods are called on server
> startup.
> But sending GET requests does not seem to be intercepted and always
> result in 404.
>
> Seeking integration examples, one mostly finds tips about using
> Context but this interface seems to be deprecated in jetty 7.5 so
> before I dig deeper I would be happy to know if someone here has
> already integrated Guice with Embedded Jetty and would be willing to
> share his thoughts.
>
> My motivation for having Guice right at the servlet entry point level
> is simplicity, I love the framework and among other great features the
> small "quick wins", for example the @Singleton.
>
>
> Prior to Guice, our mapping code looked like this:
>
> __addServlet(ServletContextHandler servletContextHandler, String
> path, Class<? extends Servlet> servletClazz) {
> try {
> servletContextHandler.addServlet(new
> ServletHolder(servletClazz.newInstance()), path);
> } catch (Throwable e) {
> throw new RuntimeException(e);
> }
> }
>
>
>
> Thank you,
> Maxim.
>
> --
> You received this message because you are subscribed to the Google
> Groups "google-guice" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-guice/-/hJNBXVtWUF4J.
> To post to this group, send email to google...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-guice...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-guice?hl=en.


Jared Bunting

unread,
Jun 28, 2012, 6:38:13 PM6/28/12
to google...@googlegroups.com
I don't have a complete example of working code at the moment that I
can share but I was able to try out yours. Turns out I forgot a line.
Jetty wants to know that theres *something* to send a request to, and
apparently a filter doesn't cut it. So I've been able to fix that with
this line:

servletContextHandler.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class.getCanonicalName(),
"/");

-Jared

On Thu 28 Jun 2012 01:40:39 PM CDT, Maxim Veksler wrote:
> Jared,
>
> Thanks for your response but even after switching to using the
> injector to create the filter it still does not seem to intercept the
> calls.
> If you could share a complete configuration of your working code it
> would be wonderful.
>
> My integration currently looks as following:
>
> Injector injector = Guice.createInjector(
> new MadServingModule(),
> new MadMockModule(),
> new MadTrackModule(),
> new MadMiscModule());
>
> HandlerCollection handlerCollection = new HandlerCollection();
> ContextHandlerCollection contexts = new
> ContextHandlerCollection();
> handlerCollection.addHandler(contexts);
> //ContextHandler contextHandler = new ContextHandler();
>
> ServletContextHandler servletContextHandler = new
> ServletContextHandler(contexts, "/");
> servletContextHandler.addFilter(new
> FilterHolder(injector.getInstance(GuiceFilter.class)), "/*",
> FilterMapping.ALL);
> servletContextHandler.addFilter(GzipFilter.class, "/*",
> FilterMapping.ALL);
>
> server.setHandler(handlerCollection);
> server.start();
>
>
> Maxim.
> <https://groups.google.com/d/msg/google-guice/-/hJNBXVtWUF4J>.
> > To post to this group, send email to
> google...@googlegroups.com <mailto:google...@googlegroups.com>.
> > To unsubscribe from this group, send email to
> > google-guice...@googlegroups.com
> <mailto:google-guice%2Bunsu...@googlegroups.com>.
> > For more options, visit this group at
> > http://groups.google.com/group/google-guice?hl=en
> <http://groups.google.com/group/google-guice?hl=en>.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "google-guice" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-guice/-/mMs5yinsNQYJ.

Maxim Veksler

unread,
Jun 30, 2012, 10:33:19 AM6/30/12
to google...@googlegroups.com
Thank you Jared.

Adding the servlet was indeed what was missing from the mix to get Jetty configured.
I'm attaching the complete sample of my configurations, for other people as well as for documentation.

Please note that at least from my findings so far, it is not mandatory to inject the GuiceFilter into jetty handles and the association with guice happens at the incoming request instead. How the injection takes place I do not yet exactly know but will be reading the code to understand. I guess it's smart usage of ThreadLocal somehow.

Here is the complete working code for Jetty & Guice based servlet filtering:



public class GuiceLauncher {
    public static void main(String[] args) throws Exception {
        // Create SelectChannelConnector on port 3583 and attach to server.
        Server server = new Server(3583);
        server.setSendDateHeader(true);
        server.setSendServerVersion(false);

        Guice.createInjector(
                new MadServingModule(),
                new MadMockModule(),
                new MadTrackModule(),
                new MadMiscModule());

        ServletContextHandler servletContextHandler = new ServletContextHandler(new ContextHandler(), "/");
        servletContextHandler.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
        servletContextHandler.addFilter(GuiceFilter.class, "/*", FilterMapping.ALL);
        servletContextHandler.addFilter(GzipFilter.class, "/*", FilterMapping.ALL);

Gili

unread,
Nov 6, 2012, 11:33:12 PM11/6/12
to google...@googlegroups.com
FYI, I posted this bug report: https://bugs.eclipse.org/bugs/show_bug.cgi?id=393738

Gili

Richard Mutezintare

unread,
Nov 7, 2012, 9:43:26 AM11/7/12
to google...@googlegroups.com
I am no sure whether this is a bug or a feature. I have observed the behavior you describe in Websphere, Tomcat and Jetty. After some debugging, I can confirm that the GuiceFilter get called, however you still get a 404. To overcome that, the mapping of the GuiceFilter remains /* and in the servlet configurator, I bind all other filters to /something/*. With that configuration, I no longer get 404.


On Tue, Nov 6, 2012 at 11:33 PM, Gili <cow...@bbs.darktech.org> wrote:

Gili

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-guice/-/tzyuNTZZBFoJ.

cowwoc

unread,
Nov 7, 2012, 10:50:26 AM11/7/12
to google...@googlegroups.com

    My explanation for why this is a bug is that there is already an implicitly registered servlet that returns HTTP 404 on unbound URIs, so why should that behave any differently from an explicitly bound servlet that does the same? Furthermore, we should be able to filter servlets that return HTTP 404. You might want to override their content bodies, add headers, etc. so there is no good reason for saying that filters don't need to be called on addresses that return HTTP 404.

Gili
Reply all
Reply to author
Forward
0 new messages