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