The warning comes from here (InternalServletModule.java):

@Singleton
  static class BackwardsCompatibleServletContextProvider implements
Provider<ServletContext> {
    private ServletContext injectedServletContext;

    // This setter is called by the GuiceServletContextListener
    void set(ServletContext injectedServletContext) {
      this.injectedServletContext = injectedServletContext;
    }

    public ServletContext get() {
      if (null != injectedServletContext) {
        return injectedServletContext;
      }

      Logger.getLogger(InternalServletModule.class.getName())
          .warning("You are attempting to use a deprecated API (specifically,"
          + " attempting to @Inject ServletContext inside an eagerly created"
          + " singleton. While we allow this for backwards compatibility, be"
          + " warned that this MAY have unexpected behavior if you have more"
          + " than one injector (with ServletModule) running in the same JVM."
          + " Please consult the Guice documentation at"
          + " http://code.google.com/p/google-guice/wiki/Servlets for more"
          + " information.");
      return GuiceFilter.getServletContext();
    }
  }

The setter is called by the GuiceServletContextListener:
 Injector injector = getInjector();
 
injector.getInstance(InternalServletModule.BackwardsCompatibleServletContextProvider.class)
        .set(servletContext);

It seems that binding TestServlet.class in configureServlets() is
calling BackwardsCompatibleServletContextProvider.get() before
BackwardsCompatibleServletContextProvider.set() and hence the warning.

Injecting a ServletContext with a provider should not trigger the warning:
Provider<ServletContext> serlvetContext

On Tue, Aug 16, 2011 at 2:35 PM, Jared Bunting
<[email protected]> wrote:
> Actually, this deserves a touch more investigation.  You are correct, in
> your code, even changing Stage.DEVELOPMENT to Stage.PRODUCTION will not
> generate the error.
>
> However, doing that and adding
>
>  bind(TestServlet.class)
>
> to TestServletModule will.
>
> It appears that classes referenced solely through serve().with() and
> filter().with() aren't actually bound in the same way as bind().  This
> is important because there are classes in shiro that are not filters
> that require the ServletContext.  In addition, shiro filter chains are
> not bound using the filter() method.
>
> -Jared
>
> On 08/16/2011 08:24 AM, Jared Bunting wrote:
>> The warning specifies "eager singleton".  You've worked around that by
>> making your singleton non-eager.
>>
>> Now try creating your injector with "Stage.PRODUCTION".  In production
>> stage, all singletons are eager.  Hence the problem.
>>
>> -Jared
>>
>> On 08/16/2011 04:56 AM, Filipe Sousa wrote:
>>> On Mon, Aug 15, 2011 at 1:37 PM, Jared Bunting
>>> <[email protected]> wrote:
>>> ...
>>>>> it would solve the following issue
>>>>> https://issues.apache.org/jira/browse/SHIRO-318 as we would be able to
>>>>> inject ServletContext.
>>>> I don't believe this is true.  When I attempted to define a singleton in
>>>> a ServletModule that injected ServletContext, I got the same deprecation
>>>> warning.  I am led to believe that guice-servlets does not intend to
>>>> support any ServletContext injected into a singleton.
>>> I'm not so sure about that. I did a simple test with ServletModule and
>>> I'm not getting the warning:
>>>
>>> public class GuiceListener extends GuiceServletContextListener {
>>>      @Override
>>>      protected Injector getInjector() {
>>>              return Guice.createInjector(Stage.DEVELOPMENT, new 
>>> TestServletModule());
>>>      }
>>> }
>>>
>>> public class TestServletModule extends ServletModule {
>>>      @Override
>>>      protected void configureServlets() {
>>>              serve("/test").with(TestServlet.class);
>>>      }
>>> }
>>>
>>> @Singleton
>>> public class TestSingleton {
>>>      private final ServletContext context;
>>>
>>>      @Inject
>>>      public TestSingleton(ServletContext context) {
>>>              this.context = context;
>>>      }
>>> }
>>>
>>> @Singleton
>>> public class TestServlet extends HttpServlet {
>>>      private static final long serialVersionUID = 1L;
>>>      private final ServletContext context1;
>>>      private final Provider<ServletContext> context2;
>>>      private final TestSingleton testSingleton;
>>>
>>>      @Inject
>>>      public TestServlet(ServletContext context1, Provider<ServletContext> 
>>> context2,
>>>                      TestSingleton testSingleton) {
>>>              this.context1 = context1;
>>>              this.context2 = context2;
>>>              this.testSingleton = testSingleton;
>>>      }
>>>
>>>      @Override
>>>      protected void doGet(HttpServletRequest req, HttpServletResponse resp)
>>>                      throws ServletException, IOException {
>>>              PrintWriter w = resp.getWriter();
>>>              w.print("context1=");
>>>              w.println(context1);
>>>              w.print("context2=");
>>>              w.println(context2.get());
>>>      }
>>> }
>>>
>
>



-- 
Filipe Sousa

Reply via email to