Skip to content

Commit

Permalink
Issue #4700 ServletContext.createXXX methods should throw Unsupported…
Browse files Browse the repository at this point in the history
…OperationException (#4701)

* Issue #4700 ServletContext.createXXX methods should throw UnsupportedOperationException

Signed-off-by: Jan Bartel <janb@webtide.com>
  • Loading branch information
janbartel committed Mar 25, 2020
1 parent 57324f3 commit 0c20622
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public <T extends AsyncListener> T createListener(Class<T> clazz) throws Servlet
{
ContextHandler contextHandler = state().getContextHandler();
if (contextHandler != null)
return contextHandler.getServletContext().createListener(clazz);
return contextHandler.getServletContext().createInstance(clazz);
try
{
return clazz.getDeclaredConstructor().newInstance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2713,7 +2713,7 @@ public void addListener(Class<? extends EventListener> listenerClass)
LOG.warn(UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER, "addListener(Class)");
}

protected <T> T createInstance(Class<T> clazz) throws ServletException
public <T> T createInstance(Class<T> clazz) throws ServletException
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,7 @@ public boolean setInitParameter(String name, String value)
}

@Override
protected <T> T createInstance(Class<T> clazz) throws ServletException
public <T> T createInstance(Class<T> clazz) throws ServletException
{
return _objFactory.decorate(super.createInstance(clazz));
}
Expand Down Expand Up @@ -1424,6 +1424,42 @@ public void setSessionTimeout(int sessionTimeout)
_sessionHandler.setMaxInactiveInterval((int)tmp);
}
}

@Override
public <T extends Servlet> T createServlet(Class<T> clazz) throws ServletException
{
if (!_enabled)
throw new UnsupportedOperationException();
return super.createServlet(clazz);
}

@Override
public <T extends Filter> T createFilter(Class<T> clazz) throws ServletException
{
if (!_enabled)
throw new UnsupportedOperationException();
return super.createFilter(clazz);
}

@Override
public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException
{
if (!_enabled)
throw new UnsupportedOperationException();
try
{
checkListener(clazz);
}
catch (IllegalArgumentException e)
{
//Bizarrely, according to the spec, it is NOT an error to create an instance of
//a ServletContextListener from inside a ServletContextListener, but it IS an error
//to call addListener with one!
if (!ServletContextListener.class.isAssignableFrom(clazz))
throw e;
}
return super.createListener(clazz);
}

@Override
public void addListener(String className)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,66 @@ public void sessionIdChanged(HttpSessionEvent event, String oldSessionId)
}
}

/**
* ServletContextListener that is designed to be added programmatically,
* which should make all of the createListener, createServlet, createFilter
* methods fail with UnsupportedOperationException
*
*/
public class CreatingSCL implements ServletContextListener
{
@Override
public void contextInitialized(ServletContextEvent sce)
{
try
{
sce.getServletContext().createFilter(MyFilter.class);
sce.getServletContext().setAttribute("CreatingSCL.filter", Boolean.FALSE);
}
catch (UnsupportedOperationException e)
{
sce.getServletContext().setAttribute("CreatingSCL.filter", Boolean.TRUE);
}
catch (Exception e)
{
fail(e);
}

try
{
sce.getServletContext().createServlet(HelloServlet.class);
sce.getServletContext().setAttribute("CreatingSCL.servlet", Boolean.FALSE);
}
catch (UnsupportedOperationException e)
{
sce.getServletContext().setAttribute("CreatingSCL.servlet", Boolean.TRUE);
}
catch (Exception e)
{
fail(e);
}

try
{
sce.getServletContext().createListener(MyContextListener.class);
sce.getServletContext().setAttribute("CreatingSCL.listener", Boolean.FALSE);
}
catch (UnsupportedOperationException e)
{
sce.getServletContext().setAttribute("CreatingSCL.listener", Boolean.TRUE);
}
catch (Exception e)
{
fail(e);
}
}

@Override
public void contextDestroyed(ServletContextEvent sce)
{
}
}

public class InitialListener implements ServletContextListener
{
@Override
Expand Down Expand Up @@ -499,7 +559,7 @@ public void contextInitialized(ServletContextEvent sce)
{
MyContextListener contextListener = sce.getServletContext().createListener(MyContextListener.class);
sce.getServletContext().addListener(contextListener);
fail("Adding SCI from an SCI!");
fail("Adding SCL from an SCL!");
}
catch (IllegalArgumentException e)
{
Expand Down Expand Up @@ -821,6 +881,76 @@ public void testAddServletFromServlet() throws Exception
fail(e);
}
}

@Test
public void testCreateMethodsFromSCI() throws Exception
{
//A filter can be created by an SCI
ContextHandlerCollection contexts = new ContextHandlerCollection();
_server.setHandler(contexts);

ServletContextHandler root = new ServletContextHandler(contexts, "/");
class FilterCreatingSCI implements ServletContainerInitializer
{
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
{
try
{
ctx.createFilter(MyFilter.class);
}
catch (Exception e)
{
fail(e);
}

try
{
ctx.createServlet(HelloServlet.class);
}
catch (Exception e)
{
fail(e);
}

try
{
ctx.createListener(MyContextListener.class);
}
catch (Exception e)
{
fail(e);
}
}
}

root.addBean(new MySCIStarter(root.getServletContext(), new FilterCreatingSCI()), true);
_server.start();
}

@Test
public void testCreateMethodsFromSCL() throws Exception
{
//A filter can be created by an SCI
ContextHandlerCollection contexts = new ContextHandlerCollection();
_server.setHandler(contexts);

ServletContextHandler root = new ServletContextHandler(contexts, "/");
class ListenerCreatingSCI implements ServletContainerInitializer
{
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
{
ctx.addListener(new CreatingSCL());
}
}

root.addBean(new MySCIStarter(root.getServletContext(), new ListenerCreatingSCI()), true);
_server.start();
assertTrue((Boolean)root.getServletContext().getAttribute("CreatingSCL.filter"));
assertTrue((Boolean)root.getServletContext().getAttribute("CreatingSCL.servlet"));
assertTrue((Boolean)root.getServletContext().getAttribute("CreatingSCL.listener"));
}

@Test
public void testAddFilterFromServlet() throws Exception
Expand Down

0 comments on commit 0c20622

Please sign in to comment.