Does Jersey-Giz not handle related resources if the injector is a child?

I use Jersey-Guice to customize the application in Jersey following this pattern . Everything works fine if the Injector returned by the GuiceServletContextListener.getInjector() method is created by Guice.createInjector() . If this injector is a descendant of another injector, then bound resources (for example, MyResource in the code below) are never added to the ResourceConfig Jersey, and Jersey complaining about the lack of root resources. I do not think that related resources are even scanned, because the usual "INFO: Register my.example.MyResource as the root resource class" does not appear in the log.

Any ideas why this might happen? Both versions are shown below.

As an additional question: I am trying to use a child injector because I want to configure the application data service object in my Main () class. This requires access only to Jersey resources. I still need it to be introduced into Jersey resources.

If there is a better way to split a singleton application between the Injector application and the servlet injector (better than my current servlet injector approach, which is a child of the application injector), let me know.

This version works.

 public class MyConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new ServletModule() { @Override protected void configureServlets() { bind(MyResource.class); serve("*").with(GuiceContainer.class); } }); } } 

The following code does not work.

  public class MyConfig extends GuiceServletContextListener { final Injector parentInjector; public MyConfig(Injector injector) { this.parentInjector = injector; } @Override protected Injector getInjector() { return parentInjector.getChildInjector(new ServletModule() { @Override protected void configureServlets() { bind(MyResource.class); serve("*").with(GuiceContainer.class); } }); } } 
+2
source share
1 answer

I realized this after some pleasure with the debugger.

Resources are discovered by iterating over injector connections, checking those that are resources or suppliers. The injector used is injected into the GuiceContainer using the following constructor: public GuiceContainer(@Inject injector) . Without explicit binding for the GuiceContainer.class specified in the child injector, the parent (i.e., Root) injector is used to instantiate (binding exactly at the moment, I think), and therefore the parent (and not child) injector is injected into the instance GuiceContainer.

The fix is simple:

Explicitly bind GuiceContainer.class to the child injector. The following code works

  public class MyConfig extends GuiceServletContextListener { final Injector parentInjector; public MyConfig(Injector injector) { this.parentInjector = injector; } @Override protected Injector getInjector() { return parentInjector.getChildInjector(new ServletModule() { @Override protected void configureServlets() { /* Explicitly bind GuiceContainer so that * the child, not root, injector is injected * into its constructor. */ bind(GuiceContainer.class); bind(MyResource.class); serve("*").with(GuiceContainer.class); } }); } } 
+4
source

All Articles