Hello,
I just had problem with ServletContext injection.
After deployment of Guiced war to my Tomcat I get this error:
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.
Nov 11, 2013 5:11:38 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
Well, the error message "SEVERE: Error listenerStart" is pretty
straightforward, isn't it? No, I'm just kidding. This was like a nightmare to
figure out whats wrong. So, I would like to help to get rid of such errors by
changing concept. Not only by telling how to solve it.
How to reproduce this error:
1. I have class inheritance like this ProdConfig > AppConfig >
GuiceServletContextListener + HttpSessionListener
2. ProdConfig contains final Injector variable. So, injector is created before
contextInitialized().
3. Injector contains a module, which depends on ServletContext (Apache Shiro
lets say)
4. Finally, create Injector in Production stage. (Eager creation)
5. Tramdada, you got the same message.
How to solve:
1. Set stage to Development. (Lazy creation)
2. Change Injector variable to be non-final and create it inside getInjector().
(It will be called inside contextInitialized() first time.)
How to solve by concept:
1. Lets say Guice Injector is highest point of abstraction from application
point of view.
2. I think ServletContext is one level of abstraction higher.
3. So, why we do not stick with IoC/DI pattern and let somebody else to resolve
this dependency.
4. The idea is to overload GuiceServletContextListener.getInjector() with
GuiceServletContextListener.getInjector(ServletContext.class)
5. And also it would be nice to have ServletModule constructor with
ServletContext.class argument.
6. Well, this take a bit of simplicity but bring more confidence of your code.
Because, ServletModule(ServletContext.class) cannot be created via
GuiceServletContextListener constructor or just as final variable, but only via
getInjector(ServletContext.class) by concept.
or
1. At least there could be one more error message in
BackwardsCompatibleServletContextProvider.get() when
GuiceFilter.getServletContext() is null. Something like "You probably created
injector in Production stage (or with eagerly singletons) outside
GuiceServletContextListener.getInjector() method."
PS: If this is somehow feasible for you to put it into Guice 4 or higher. I'm
willing to help with some contribution.
Best regards,
Milan
Original issue reported on code.google.com by milan.ba...@gmail.com on 12 Nov 2013 at 10:34
Original issue reported on code.google.com by
milan.ba...@gmail.com
on 12 Nov 2013 at 10:34