On Fri, 2008-06-20 at 12:05 +0200, Matthias Berndt wrote: > On Fri, Jun 20, 2008 at 11:46:39AM +0200, simon wrote: > > Well, there are two types of PhaseListener: > > * global ones (JSF1.1 and later) > > * per-view phase listeners (JSF1.2) > > I'm talking about the traditional global one above. I don't know much > > about the newer facility. > > I'm sorry, but I didn't different kinds of PhaseListener until now. > > > For the official definition of behaviour you would need to read the JSF > > specification. > > ... I'll do so, but this may take some time ... :-) > > > What on earth would those methods do when called from the > > constructor of a global PhaseListener, whose lifetime spans many > > different requests? > > They do what I mentioned. I read properties out of web.xml and some > other files. These properties influence the listerners runtime behavior. > I don't like to read them every time and I also don't like to use a > poor-mans-cache like: If not read, read for the first time an store them > in memory. So I tried to read them once in the constructor. > > Is there a better way to access the ServletContext in a PhaseListener > thn using FacesContext.getExternalContext()? What is it?
This is a bit of a flaw in the JSF spec. They don't cleanly separate the concept of "global" resources (init parameters etc) from per-request resources. The ExternalContext object is the only way to get at this sort of data via the JSF apis (AFAIK) but because it provides access to both types of resources it isn't sane to access it outside of a request. What you say jboss/glassfish is doing sounds really weird to me. They must be either: (a) providing a FacesContext object that is only partially initialised, so that some methods work but other methods will just blow up if called. (b) creating the PhaseListener "on demand" in the context of the first request to the webapp, in which case all methods will work but will access a request that is pretty much random. I can't see any other options.. In your particular situation, I would personally write a ServletContextListener that stores the ServletContext as a thread-local or just a static variable. Then in the PhaseListener, retrieve the data directly from the ServletContextListener. In other words, bypass JSF and get the data direct. Regards, Simon

