pombreda / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
0 stars 1 forks source link

Guice Servlet Contex injection issue/enchancment #781

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
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