Static Servlet Context variable

Luiggi Mendoza picture Luiggi Mendoza · Mar 26, 2012 · Viewed 8.5k times · Source

I have read from the question How to gain access to a ServletContext instance from any method? that if I want to access the Servlet Context from any class in my Java web project I can declare a static field that points to the ServletContext from ServletContextListener, but a static field is a bad practice in Java web applications because the GC can't collect it until the JVM is turned off (correct me if I'm wrong in this point). Is there another way to access the ServletContext without using a listener or receiving it as a parameter? There is another workaround for solve this problem? I'm using JSF 1.2 and JBoss 5.1 GA for the Web Application.

Note: I know I can use

(ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();

to access the ServletContext, but there is a method that runs at startup that needs to access the ServletContext and the FacesContext.getCurrentInstance() has not been initialized.

UPDATE:

We need to load some IP's from the web.xml into String constants when the web application starts up. To do this, we have created a Singleton class that loads the context-params in variables and then fill the String constants with some values of the Singleton class. This Singleton class manages lot of data and is giving out of memory exception errors. To fix this problem, we're modifying the Singleton class to be a simple class that is loaded as a ServerContext attribute, but then the String constants can't be loaded for the absence of the instance of this (not anymore) Singleton.

Answer

BalusC picture BalusC · Mar 27, 2012

I'm not sure why you need a singleton. Just create one bean which you store in the application scope.

@Override
public void contextInitialized(ServletContextEvent event) {
    ServletContext context = event.getServletContext();
    Set<String> ips = parseContextParamSomehow(context.getInitParam("ips"));
    Manager manager = new Manager();
    manager.setIps(ips);
    context.setAttribute("manager", manager);
}

It'll be available by #{manager} in EL context. Also as managed property of an arbitraty JSF managed bean. An alternative is to create an application scoped JSF managed bean and do the job in its constructor, but you're then postponing its construction to the first HTTP request which involves the bean.