409449 Ensure servlets, filters and listeners added via dynamic registration, annotations or descriptors are cleaned on context restarts

This commit is contained in:
Jan Bartel 2013-06-12 15:41:03 +10:00
parent 6150f29382
commit 64d979a780
5 changed files with 64 additions and 28 deletions

View File

@ -149,6 +149,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
private Object _contextAttributeListeners;
private Object _requestListeners;
private Object _requestAttributeListeners;
private Object _durableListeners;
private Map<String, Object> _managedAttributes;
private String[] _protectedTargets;
private final CopyOnWriteArrayList<AliasCheck> _aliasChecks = new CopyOnWriteArrayList<ContextHandler.AliasCheck>();
@ -591,6 +592,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
*/
public void addEventListener(EventListener listener)
{
//Only listeners added before the context starts last through a stop/start cycle
if (!(isStarted() || isStarting()))
_durableListeners = LazyList.add(_durableListeners, listener);
setEventListeners((EventListener[])LazyList.addToArray(getEventListeners(),listener,EventListener.class));
}
@ -607,6 +612,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
{
}
/* ------------------------------------------------------------ */
/**
* @return true if this context is accepting new requests
@ -816,6 +823,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
((ServletContextListener)LazyList.get(_contextListeners,i)).contextDestroyed(event);
}
}
//remove all non-durable listeners
setEventListeners((EventListener[])LazyList.toArray(_durableListeners, EventListener.class));
_durableListeners = null;
if (_errorHandler != null)
_errorHandler.stop();

View File

@ -1007,8 +1007,6 @@ public class ServletContextHandler extends ContextHandler
if (!_enabled)
throw new UnsupportedOperationException();
//TODO handle partial registrations
final ServletHandler handler = ServletContextHandler.this.getServletHandler();
ServletHolder holder = handler.getServlet(servletName);
if (holder == null)

View File

@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.ListIterator;
import java.util.Set;
import java.util.List;
import java.util.Map;
@ -197,28 +198,70 @@ public class ServletHandler extends ScopedHandler
throws Exception
{
super.doStop();
// Stop filters
List<FilterHolder> filterHolders = new ArrayList<FilterHolder>();
List<FilterMapping> filterMappings = LazyList.array2List(_filterMappings);
if (_filters!=null)
{
for (int i=_filters.length; i-->0;)
{
try { _filters[i].stop(); }catch(Exception e){LOG.warn(Log.EXCEPTION,e);}
if (_filters[i].getSource() != Source.EMBEDDED)
{
//remove all of the mappings that were for non-embedded filters
_filterNameMap.remove(_filters[i].getName());
//remove any mappings associated with this filter
ListIterator<FilterMapping> fmitor = filterMappings.listIterator();
while (fmitor.hasNext())
{
FilterMapping fm = fmitor.next();
if (fm.getFilterName().equals(_filters[i].getName()))
fmitor.remove();
}
}
else
filterHolders.add(_filters[i]); //only retain embedded
}
}
_filters = (FilterHolder[]) LazyList.toArray(filterHolders, FilterHolder.class);
_filterMappings = (FilterMapping[]) LazyList.toArray(filterMappings, FilterMapping.class);
_matchAfterIndex = (_filterMappings == null || _filterMappings.length == 0 ? -1 : _filterMappings.length-1);
_matchBeforeIndex = -1;
// Stop servlets
List<ServletHolder> servletHolders = new ArrayList<ServletHolder>(); //will be remaining servlets
List<ServletMapping> servletMappings = LazyList.array2List(_servletMappings); //will be remaining mappings
if (_servlets!=null)
{
for (int i=_servlets.length; i-->0;)
{
try { _servlets[i].stop(); }catch(Exception e){LOG.warn(Log.EXCEPTION,e);}
if (_servlets[i].getSource() != Source.EMBEDDED)
{
//remove from servlet name map
_servletNameMap.remove(_servlets[i].getName());
//remove any mappings associated with this servlet
ListIterator<ServletMapping> smitor = servletMappings.listIterator();
while (smitor.hasNext())
{
ServletMapping sm = smitor.next();
if (sm.getServletName().equals(_servlets[i].getName()))
smitor.remove();
}
}
else
servletHolders.add(_servlets[i]); //only retain embedded
}
}
_servlets = (ServletHolder[]) LazyList.toArray(servletHolders, ServletHolder.class);
_servletMappings = (ServletMapping[])LazyList.toArray(servletMappings, ServletMapping.class);
//will be regenerated on next start
_filterPathMappings=null;
_filterNameMappings=null;
_filterNameMappings=null;
_servletPathMap=null;
}
@ -797,7 +840,8 @@ public class ServletHandler extends ScopedHandler
{
ServletHolder holder = newServletHolder(Holder.Source.EMBEDDED);
holder.setHeldClass(servlet);
setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
//DUPLICATES adding servlet from addServletWithMapping(holder, pathSpec)?
//setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
addServletWithMapping(holder,pathSpec);
return holder;
@ -969,7 +1013,7 @@ public class ServletHandler extends ScopedHandler
*/
public FilterHolder addFilterWithMapping (String className,String pathSpec,int dispatches)
{
FilterHolder holder = newFilterHolder(null);
FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
holder.setName(className+"-"+_filters.length);
holder.setClassName(className);
@ -1118,7 +1162,7 @@ public class ServletHandler extends ScopedHandler
{
//programmatically defined filter mappings are prepended to mapping list in the order
//in which they were defined. In other words, insert this mapping at the tail of the
//programmatically added filter mappings, BEFORE the first web.xml defined filter mapping.
//programmatically prepended filter mappings, BEFORE the first web.xml defined filter mapping.
if (_matchBeforeIndex < 0)
{
@ -1161,14 +1205,15 @@ public class ServletHandler extends ScopedHandler
{
if (pos < 0)
throw new IllegalArgumentException("FilterMapping insertion pos < 0");
FilterMapping[] mappings = getFilterMappings();
if (mappings==null || mappings.length==0)
{
return new FilterMapping[] {mapping};
}
FilterMapping[] new_mappings = new FilterMapping[mappings.length+1];
if (before)
{
//copy existing filter mappings up to but not including the pos

View File

@ -991,16 +991,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
}
}
/* ------------------------------------------------------------ */
/** Add EventListener
* Conveniance method that calls {@link #setEventListeners(EventListener[])}
* @param listener
*/
@Override
public void addEventListener(EventListener listener)
{
setEventListeners(LazyList.addToArray(getEventListeners(), listener, EventListener.class));
}
/* ------------------------------------------------------------ */

View File

@ -121,16 +121,8 @@ public class WebXmlConfiguration extends AbstractConfiguration
@Override
public void deconfigure (WebAppContext context) throws Exception
{
// TODO preserve any configuration that pre-existed.
ServletHandler _servletHandler = context.getServletHandler();
_servletHandler.setFilters(null);
_servletHandler.setFilterMappings(null);
_servletHandler.setServlets(null);
_servletHandler.setServletMappings(null);
context.setEventListeners(null);
context.setWelcomeFiles(null);
if (context.getErrorHandler() instanceof ErrorPageErrorHandler)