I previously wrote about a way to get ahold of the Guice injector in a JSP by putting it in the ServletContext; however, I have another case where I need it in a class that doesn’t have access to the ServletContext, either. The class happens to be a background task that implements the Deferrable interface, which for sake of interface simplicity does not provide access to the ServletContext even though the task does in fact run in a servlet.
The solution is simply to create the Guice injector in a static factory:
package com.roa.server.guice; import com.google.inject.Guice; import com.google.inject.Injector; public class GuiceFactory { private static final Injector inj = Guice.createInjector(...); public static Injector getInjector() { return inj; } }
Now any class that needs access to a Guice-managed object can get it easily, including the ultra-simplified Guice context listener that’s registered in web.xml:
package com.roa.server.guice; import com.google.inject.Injector; import com.google.inject.servlet.GuiceServletContextListener; public class GuiceConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return GuiceFactory.getInjector(); } }
WARNING: this works fine in AppEngine because there’s only one WAR per JVM in that environment. If you’re not running in AppEngine and have multiple WARs in a single JVM, as is commonly the case, you may or may not want a single Guice injector for the whole JVM. I have not tested it, but I would think you wouldn’t be able to use Guice ServletModules in that case.