Getting a ServletContext
natros opened this issue · comments
I have some modules that needs a ServletContext
. The problem is that JerseyGuiceServletContextListener#modules()
is being called before JerseyGuiceServletContextListener#contextInitialized()
. Is there any way to pass a ServletContext
to a module.
I'm using apache shiro security framework with guice support. The ShiroWebModule
needs a ServletContext
http://shiro.apache.org/static/1.2.1/apidocs/org/apache/shiro/guice/web/ShiroWebModule.html#ShiroWebModule(javax.servlet.ServletContext)
Try...
class MyContextModule extends com.squarespace.jersey2.guice.JerseyModule {
@Override
protected void configure() {
bind(ServletContext.class).toProvider(ContextProvider.class);
}
private static class ContextProvider implements Provider<ServletContext>
@Inject
private Provider<ServiceLocator> locator;
@Override
public ServletContext get() {
return locator.get().getService(ServletContext.class);
}
}
}
Make sure the binding is declared in a JerseyModule.
I don't think this is going to work. I need a instance of ServletContext inside the module.
With the jersey 1.x I override contextInitialized to get the servlet context.
public class MyListener extends GuiceServletContextListener {
private ServletContext servletContext;
@Override
protected Injector getInjector() {
return Guice.createInjector(new ShiroWebModule(servletContext));
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
servletContext = servletContextEvent.getServletContext();
super.contextInitialized(servletContextEvent);
}
}
I'm trying this
public abstract class Jersey2GuiceServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
ServiceLocator serviceLocator = BootstrapUtils.newServiceLocator();
BootstrapUtils.newInjector(serviceLocator, stage(), modules(event.getServletContext()));
BootstrapUtils.install(serviceLocator);
}
protected abstract Stage stage();
protected abstract List<? extends Module> modules(ServletContext servletContext);
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
and
public class GuiceListener extends Jersey2GuiceServletContextListener {
@Override
protected Stage stage() {
return DEVELOPMENT;
}
@Override
protected List<? extends Module> modules(ServletContext servletContext) {
return newArrayList(new ShiroWebModule(servletContext));
}
}
I see. The reason why this library isn't using contextInitialized
is because it's called too late in the initialization chain. One part of your app gets potentially initialized with HK2's own ServiceLocator and the other half by this librarie's ServiceLocator.
A much safer approach is to use Jersey's own ServiceLocatorGenerator
SPI (see JerseyServiceLocatorGeneratorSPI) or bootstrap it from a main() method (we do the latter). But neither of that is really helping you with ShiroWebModule. I think that class has a conceptual dependency problem.