Issue #4700 ServletContext.createXXX methods should throw UnsupportedOperationException (#4701)

* Issue #4700 ServletContext.createXXX methods should throw UnsupportedOperationException

Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
Jan Bartel 2020-03-25 11:17:05 +01:00 committed by GitHub
parent 57324f3cca
commit 0c20622648
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 170 additions and 4 deletions

View File

@ -77,7 +77,7 @@ public class AsyncContextState implements AsyncContext
{
ContextHandler contextHandler = state().getContextHandler();
if (contextHandler != null)
return contextHandler.getServletContext().createListener(clazz);
return contextHandler.getServletContext().createInstance(clazz);
try
{
return clazz.getDeclaredConstructor().newInstance();

View File

@ -2713,7 +2713,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
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
{

View File

@ -1256,7 +1256,7 @@ public class ServletContextHandler extends ContextHandler
}
@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));
}
@ -1424,6 +1424,42 @@ public class ServletContextHandler extends ContextHandler
_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)

View File

@ -464,6 +464,66 @@ public class ServletContextHandlerTest
}
}
/**
* 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
@ -499,7 +559,7 @@ public class ServletContextHandlerTest
{
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)
{
@ -821,6 +881,76 @@ public class ServletContextHandlerTest
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