Discussion:
How to Disable JSP in Embedded Tomcat
Igal Sapir
2018-09-21 04:57:43 UTC
Permalink
I want to embed Tomcat in a simple application that does not use JSP, and
that sets the default servlet's listings initParam to true.

When I use the StandardContext, Tomcat.initWebappDefaults() [1] is called
and adds the default servlet and the JSP servlet. I would like to prevent
that, but hopefully without having to rewrite the whole Tomcat class nor to
subclass it.

Further, when I try to override a setting in WEB-INF/web.xml, e.g. to
specify init-param of "listings" with value "true" for the servlet
"default", I get an error that "default" is not unique, but in a regular
Tomcat deployment that works just fine.

Is there an easy way to override Tomcat.initWebappDefaults() or to prevent
it from being called?

Thanks,

Igal

[1]
https://github.com/apache/tomcat/blob/trunk/java/org/apache/catalina/startup/Tomcat.java#L918
Mark Thomas
2018-09-21 07:54:17 UTC
Permalink
Post by Igal Sapir
I want to embed Tomcat in a simple application that does not use JSP, and
that sets the default servlet's listings initParam to true.
When I use the StandardContext, Tomcat.initWebappDefaults() [1] is called
and adds the default servlet and the JSP servlet. I would like to prevent
that, but hopefully without having to rewrite the whole Tomcat class nor to
subclass it.
Further, when I try to override a setting in WEB-INF/web.xml, e.g. to
specify init-param of "listings" with value "true" for the servlet
"default", I get an error that "default" is not unique, but in a regular
Tomcat deployment that works just fine.
Is there an easy way to override Tomcat.initWebappDefaults() or to prevent
it from being called?
There are a couple few options.

Sub-classing looks to be the simplest.

You can use addContext() rather than addWebapp() but then you become
responsible for all of the configuration. If the app is simple, this
shouldn't be too much effort.

Mark
Post by Igal Sapir
Thanks,
Igal
[1]
https://github.com/apache/tomcat/blob/trunk/java/org/apache/catalina/startup/Tomcat.java#L918
---------------------------------------------------------------------
To unsubscribe, e-mail: users-***@tomcat.apache.org
For additional commands, e-mail: users-***@tomcat.apache.org
Igal Sapir
2018-09-22 00:11:41 UTC
Permalink
Mark,
Post by Igal Sapir
Post by Igal Sapir
I want to embed Tomcat in a simple application that does not use JSP, and
that sets the default servlet's listings initParam to true.
When I use the StandardContext, Tomcat.initWebappDefaults() [1] is called
and adds the default servlet and the JSP servlet. I would like to
prevent
Post by Igal Sapir
that, but hopefully without having to rewrite the whole Tomcat class nor
to
Post by Igal Sapir
subclass it.
Further, when I try to override a setting in WEB-INF/web.xml, e.g. to
specify init-param of "listings" with value "true" for the servlet
"default", I get an error that "default" is not unique, but in a regular
Tomcat deployment that works just fine.
Is there an easy way to override Tomcat.initWebappDefaults() or to
prevent
Post by Igal Sapir
it from being called?
There are a couple few options.
Sub-classing looks to be the simplest.
You can use addContext() rather than addWebapp() but then you become
responsible for all of the configuration. If the app is simple, this
shouldn't be too much effort.
The app is simple, but it is for use by other developers who may use their
own web.xml files, so I think that sub-classing would be much easier and
that's what I did.

While searching for a solution prior to asking on the mailing list, I
noticed that quite a few users were looking for a simple solution of using
addWebapp() without setting up the default servlets. What do you think
about adding a System Property that will allow to opt-out of
initWebappDefaults() and set the DefaultWebXml to null so that the web.xml
files will be parsed?

I am thinking of a property name
org.apache.catalina.startup.INIT_WEBAPP_DEFAULTS [default true], or
org.apache.catalina.startup.DISABLE_WEBAPP_DEFAULTS [default false].

Alternatively, we can add the sub-classing implementation that I used (with
the proper ASF license headers, of course). The code is pasted below in
case anyone else needs such an implementation.

I can add either solution myself if approved.

Thank you,

Igal

/**
* This class extends Tomcat to override the default functionality which
registers the default and JSP servlets, and
* prevents the parsing of the Web Application Deployment Descriptors
web.xml.
*
* Using this class therefore enables the parsing of the web.xml files, and
does not add any defaults beyond them.
*
* @author Igal Sapir
*/
public class TomcatRunner extends Tomcat {

/**
* Tomcat.addWebapp() sets DefaultWebXml to a non-null value to prevent
the parsing of the web.xml file(s).
* Here we want to parse those files, so after calling the super method
we set that value to null.
*
* @param host The host in which the context will be deployed
* @param contextPath The context mapping to use, "" for root context.
* @param docBase Base directory for the context, for static files.
* Must exist, relative to the server home
* @param config Custom context configurator helper
* @return the deployed context
* @see #addWebapp(String, String)
*/
public Context addWebapp(Host host, String contextPath, String docBase,
LifecycleListener config) {

Context ctx = super.addWebapp(host, contextPath, docBase, config);
((ContextConfig) config).setDefaultWebXml(null);

return ctx;
}

/**
* Returns a listener that does nothing, as opposed to the default one
in Tomcat which always
* adds the default servlet and the JSP servlet with the rules that are
set in the defautl web.xml
* @return a listener that does nothing.
*/
@Override
public LifecycleListener getDefaultWebXmlListener() {
// noop
return event -> {};
}

}
Igal Sapir
2018-09-22 00:28:00 UTC
Permalink
Post by Igal Sapir
Mark,
Post by Igal Sapir
Post by Igal Sapir
I want to embed Tomcat in a simple application that does not use JSP,
and
Post by Igal Sapir
that sets the default servlet's listings initParam to true.
When I use the StandardContext, Tomcat.initWebappDefaults() [1] is
called
Post by Igal Sapir
and adds the default servlet and the JSP servlet. I would like to
prevent
Post by Igal Sapir
that, but hopefully without having to rewrite the whole Tomcat class
nor to
Post by Igal Sapir
subclass it.
Further, when I try to override a setting in WEB-INF/web.xml, e.g. to
specify init-param of "listings" with value "true" for the servlet
"default", I get an error that "default" is not unique, but in a regular
Tomcat deployment that works just fine.
Is there an easy way to override Tomcat.initWebappDefaults() or to
prevent
Post by Igal Sapir
it from being called?
There are a couple few options.
Sub-classing looks to be the simplest.
You can use addContext() rather than addWebapp() but then you become
responsible for all of the configuration. If the app is simple, this
shouldn't be too much effort.
The app is simple, but it is for use by other developers who may use their
own web.xml files, so I think that sub-classing would be much easier and
that's what I did.
While searching for a solution prior to asking on the mailing list, I
noticed that quite a few users were looking for a simple solution of using
addWebapp() without setting up the default servlets. What do you think
about adding a System Property that will allow to opt-out of
initWebappDefaults() and set the DefaultWebXml to null so that the web.xml
files will be parsed?
I am thinking of a property name
org.apache.catalina.startup.INIT_WEBAPP_DEFAULTS [default true], or
org.apache.catalina.startup.DISABLE_WEBAPP_DEFAULTS [default false].
Alternatively, we can add the sub-classing implementation that I used
(with the proper ASF license headers, of course). The code is pasted below
in case anyone else needs such an implementation.
Actually, the code that I pasted below doesn't seem to play well with JSP
so I guess it's not quite ready. When I tried to add a simple JSP file I
get an NPE:

JspFactory.getDefaultFactory() returns null

java.lang.NullPointerException
org.apache.jasper.compiler.Validator$ValidateVisitor.<init>(Validator.java:524)
org.apache.jasper.compiler.Validator.validateExDirectives(Validator.java:1856)
org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:224)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:385)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:362)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:346)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:603)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:383)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
Post by Igal Sapir
I can add either solution myself if approved.
Thank you,
Igal
/**
* This class extends Tomcat to override the default functionality which
registers the default and JSP servlets, and
* prevents the parsing of the Web Application Deployment Descriptors
web.xml.
*
* Using this class therefore enables the parsing of the web.xml files,
and does not add any defaults beyond them.
*
*/
public class TomcatRunner extends Tomcat {
/**
* Tomcat.addWebapp() sets DefaultWebXml to a non-null value to
prevent the parsing of the web.xml file(s).
* Here we want to parse those files, so after calling the super
method we set that value to null.
*
* Must exist, relative to the server home
*/
public Context addWebapp(Host host, String contextPath, String
docBase, LifecycleListener config) {
Context ctx = super.addWebapp(host, contextPath, docBase, config);
((ContextConfig) config).setDefaultWebXml(null);
return ctx;
}
/**
* Returns a listener that does nothing, as opposed to the default one
in Tomcat which always
* adds the default servlet and the JSP servlet with the rules that
are set in the defautl web.xml
*/
@Override
public LifecycleListener getDefaultWebXmlListener() {
// noop
return event -> {};
}
}
Mark Thomas
2018-09-22 09:10:42 UTC
Permalink
Post by Igal Sapir
Mark,
Post by Igal Sapir
Post by Igal Sapir
I want to embed Tomcat in a simple application that does not use JSP, and
that sets the default servlet's listings initParam to true.
When I use the StandardContext, Tomcat.initWebappDefaults() [1] is called
and adds the default servlet and the JSP servlet. I would like to
prevent
Post by Igal Sapir
that, but hopefully without having to rewrite the whole Tomcat class nor
to
Post by Igal Sapir
subclass it.
Further, when I try to override a setting in WEB-INF/web.xml, e.g. to
specify init-param of "listings" with value "true" for the servlet
"default", I get an error that "default" is not unique, but in a regular
Tomcat deployment that works just fine.
Is there an easy way to override Tomcat.initWebappDefaults() or to
prevent
Post by Igal Sapir
it from being called?
There are a couple few options.
Sub-classing looks to be the simplest.
You can use addContext() rather than addWebapp() but then you become
responsible for all of the configuration. If the app is simple, this
shouldn't be too much effort.
The app is simple, but it is for use by other developers who may use their
own web.xml files, so I think that sub-classing would be much easier and
that's what I did.
While searching for a solution prior to asking on the mailing list, I
noticed that quite a few users were looking for a simple solution of using
addWebapp() without setting up the default servlets. What do you think
about adding a System Property that will allow to opt-out of
initWebappDefaults() and set the DefaultWebXml to null so that the web.xml
files will be parsed?
I have a huge dislike for using system properties for configuration. A
setter on the Tomcat class would be fine.
Post by Igal Sapir
I am thinking of a property name
org.apache.catalina.startup.INIT_WEBAPP_DEFAULTS [default true], or
org.apache.catalina.startup.DISABLE_WEBAPP_DEFAULTS [default false].
Alternatively, we can add the sub-classing implementation that I used (with
the proper ASF license headers, of course). The code is pasted below in
case anyone else needs such an implementation.
I can add either solution myself if approved.
I can imagine different users wanting to do various different things
here. I am wondering if there is a better way of handling this. The
tricky part is that we want to offer lots of flexibility in what is a
potentially complex area while keeping usage really simple.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-***@tomcat.apache.org
For additional commands, e-mail: users-***@tomcat.apache.org
Igal Sapir
2018-09-22 16:52:07 UTC
Permalink
Post by Igal Sapir
Post by Igal Sapir
Mark,
Post by Igal Sapir
Post by Igal Sapir
I want to embed Tomcat in a simple application that does not use JSP,
and
Post by Igal Sapir
Post by Igal Sapir
Post by Igal Sapir
that sets the default servlet's listings initParam to true.
When I use the StandardContext, Tomcat.initWebappDefaults() [1] is
called
Post by Igal Sapir
Post by Igal Sapir
Post by Igal Sapir
and adds the default servlet and the JSP servlet. I would like to
prevent
Post by Igal Sapir
that, but hopefully without having to rewrite the whole Tomcat class
nor
Post by Igal Sapir
Post by Igal Sapir
to
Post by Igal Sapir
subclass it.
Further, when I try to override a setting in WEB-INF/web.xml, e.g. to
specify init-param of "listings" with value "true" for the servlet
"default", I get an error that "default" is not unique, but in a
regular
Post by Igal Sapir
Post by Igal Sapir
Post by Igal Sapir
Tomcat deployment that works just fine.
Is there an easy way to override Tomcat.initWebappDefaults() or to
prevent
Post by Igal Sapir
it from being called?
There are a couple few options.
Sub-classing looks to be the simplest.
You can use addContext() rather than addWebapp() but then you become
responsible for all of the configuration. If the app is simple, this
shouldn't be too much effort.
The app is simple, but it is for use by other developers who may use
their
Post by Igal Sapir
own web.xml files, so I think that sub-classing would be much easier and
that's what I did.
While searching for a solution prior to asking on the mailing list, I
noticed that quite a few users were looking for a simple solution of
using
Post by Igal Sapir
addWebapp() without setting up the default servlets. What do you think
about adding a System Property that will allow to opt-out of
initWebappDefaults() and set the DefaultWebXml to null so that the
web.xml
Post by Igal Sapir
files will be parsed?
I have a huge dislike for using system properties for configuration. A
setter on the Tomcat class would be fine.
Even better. I'll add that.

https://bz.apache.org/bugzilla/show_bug.cgi?id=62755
Post by Igal Sapir
Post by Igal Sapir
I am thinking of a property name
org.apache.catalina.startup.INIT_WEBAPP_DEFAULTS [default true], or
org.apache.catalina.startup.DISABLE_WEBAPP_DEFAULTS [default false].
Alternatively, we can add the sub-classing implementation that I used
(with
Post by Igal Sapir
the proper ASF license headers, of course). The code is pasted below in
case anyone else needs such an implementation.
I can add either solution myself if approved.
I can imagine different users wanting to do various different things
here. I am wondering if there is a better way of handling this. The
tricky part is that we want to offer lots of flexibility in what is a
potentially complex area while keeping usage really simple.
True, but currently the reasonable defaults are always added and there is
no simple way to undo them, so allowing the user to opt-out of the defaults
will let him/her start from scratch and add only the required
configurations.

Igal

Loading...