Note that there are some explanatory texts on larger screens.

plurals
  1. POGuice Request Scope: Do I need a Provider binding for a value seeded in a servlet filter?
    primarykey
    data
    text
    <p>I'm having some problems following the Guice wiki documentation for using RequestScope (<a href="https://code.google.com/p/google-guice/wiki/ServletModule#Using_RequestScope" rel="nofollow noreferrer">https://code.google.com/p/google-guice/wiki/ServletModule#Using_RequestScope</a>).</p> <p>I am trying to set up an application where I have a request-scoped ExecutorService. My use case is patterned off the example in the documentation - I've tried to include other relevant classes for completeness.</p> <p>The main difference is that I am instantiating an instance of ExecutorService within the Filter rather than pulling a literal value out of the request parameters:</p> <pre><code>@Singleton public class ExecutorServiceScopingFilter implements Filter { public ExecutorService getExecutor() { return Executors.newFixedThreadPool(10, ThreadManager.currentRequestThreadFactory()); @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { ExecutorService executor = getExecutor(); HttpServletRequest httpRequest = (HttpServletRequest) req; httpRequest.setAttribute(Key.get(ExecutorService.class).toString(), executor); chain.doFilter(req, resp); } ... } </code></pre> <p>In my servlet module I bind the filter:</p> <pre><code>public class MyServletModule extends ServletModule { @Override protected void configureServlets() { filter("/*").through(ExecutorServiceScopingFilter.class); ... } } </code></pre> <p>And I install the module as normal in my servlet context listener (I've set up the web.xml to use the guice filter and the below listener):</p> <pre><code>public class MyServletContextListener extends GuiceServletContextListener { @Override protected Injector getInjector() { Injector injector = Guice.createInjector( Stage.PRODUCTION, new MyServletModule(), new MyExampleModule(), ... ); } } </code></pre> <p>I declare the provider in an un-scoped POJO:</p> <pre><code>class MyExampleImpl implements IMyExample { @Inject protected Provider&lt;ExecutorService&gt; executorProvider; ... } </code></pre> <p>Which I bind in a module (and is a parameter of the createInjector call in my listener above):</p> <pre><code>public class MyExampleModule extends AbstractModule { @Override protected void configure() { bind(IMyExample.class).to(MyExampleImpl.class); } } </code></pre> <p>When I start my web app, I get the following exception:</p> <blockquote> <p>com.google.inject.CreationException: Guice creation errors:</p> <p>1) No implementation for java.util.concurrent.ExecutorService was bound. while locating com.google.inject.Provider for field at com.example.MyExampleImpl.executorProvider(MyExampleImpl.java:12) at com.example.ExampleModule.configure(ExampleModule.java:23)</p> <p>1 error</p> </blockquote> <p>I have found a related question that indicates the use of a bogus binding (<a href="https://stackoverflow.com/questions/8977492/guice-cannot-inject-annotated-type-in-request-scope?rq=1">Guice: Cannot inject annotated type in Request scope</a>). The example given is:</p> <pre><code>bind(String.class) .annotatedWith(Names.named("name")) .toProvider(Providers.&lt;String&gt;of(null)); </code></pre> <p>I tried this for binding the ExecutorService and get a null for the provider (so the injector is returning the declared binding instead of using the binding defined by the filter). The use of a bogus binding is never mentioned in the official documentation.</p> <p>So a few questions to try and solve this problem and understand a bit more about how Guice operates:</p> <ol> <li><p>Do I need an explicit binding other than setting the attribute (in contrast to the Guice documentation)?</p></li> <li><p>If so, do I need to bind anything using the @RequestScope annotation?</p></li> <li><p>Do I need to make a provider that implements Provider?</p></li> <li><p>Inspecting an @Inject Injector object, I do not see the request-scoped binding for ExecutorService in the binding maps. Should I see this binding?</p></li> <li><p>Inspecting the requestScopeContext thread local variable in the ServletScope class at runtime, I do see the ExecutorService binding. This indicates that the binding is working, so I am not doing something (or doing something incorrectly) to access it.</p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload