google / google/guice

Guice Servlet Contex injection issue/enchancment

Open
#781 0 comments 0 reactions 0 assignees View on GitHub
imported
Dominant language
Java
Stars
12.7k
Forks
1.7k
Avg merge
11m
Merged PRs (30d)
2

Description

_From [milan.baran](https://code.google.com/u/117821941167764960338/) on November 12, 2013 05:34:29_

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 https://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: http://code.google.com/p/google-guice/issues/detail?id=781_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.