Table of Contents


Please read general Migration Guide page first, for common considerations that apply to migration or upgrade between versions of Apache Tomcat.

Migrating from 7.0.x to 8.0.x

This section lists all the known changes between 7.0.x and 8.0.x which may cause backwards compatibility problems when upgrading.

Java 7 required

Apache Tomcat 8.0.x requires Java 7 or later. Apache Tomcat 7.0.x required Java 6.

Specification APIs

Apache Tomcat 8 supports the Java Servlet 3.1, JavaServer Pages 2.3, Java Unified Expression Language 3.0 and Java API for WebSocket 1.1 specifications. The changes between versions of specifications may be found in the Changes appendix in each of specification documents.

Servlet 3.1 API

In JSP pages that use wildcard import syntax the new classes added in Servlet API may conflict with ones in web applications. For example, if package "a" contains class ReadListener, the following JSP page will cease to compile in Tomcat 8:

<%@page import="a.*"%>
<% ReadListener listener = new ReadListener(); %>

This happens because implicit import of javax.servlet.* and explicit import of a.* will provide conflicting definitions of class ReadListener that was added in Servlet 3.1. The solution is to use the explicit import, import="a.ReadListener".

JavaServer Pages 2.3

Unified Expression Language 3.0 added support for referencing static fields and methods. Supporting this feature in JSPs required changing the javax.servlet.jsp.el.ScopedAttributeELResolver implementation so that it also checked identifiers to see if they were names of imported classes or fields. In some circumstances, this change triggers significant slow down. This affects identifiers that may refer to a page, request, session or application scoped variable or may be undefined. When undefined, it takes significantly longer to resolve the identifier since it is now also checked to see if it is an imported class or field. To avoid this slow down, code such as:


should be replaced with:


or similar, using the appropriate scope for where the variable is defined.

Jar Scanning

During the implementation of Servlet 3.1 a number of errors were identified in Tomcat 7's Servlet 3.0 pluggability implementation. Specifically:

  • the SCI scan did not obey class loader ordering;
  • fragments in container JARs were processed rather than ignored;
  • container provided SCIs were sometimes ignored.

These issues were corrected for Tomcat 8 but not back-ported to Tomcat 7 because the fixed required significant API changes to the JarScanner component as well as changes to the configuration options.

When migrating to Tomcat 8, Jar scanning configurations will need to be reviewed and adjusted for the new configuration options and custom JarScanner implementations will need to be updated to implement the new API.

Default connector implementation

The default HTTP and AJP connector implementation has switched from the Java blocking IO implementation (BIO) to the Java non-blocking IO implementation (NIO). BIO may still be used but Servlet 3.1 and WebSocket 1.0 features that use non-blocking IO will then use blocking IO instead which may cause unexpected application behavior.

Default URL encoding

The default value of URIEncoding attribute for HTTP and AJP connectors has been changed from "ISO-8859-1" to be "UTF-8" (if "strict servlet compliance" mode is off, which is the default). This setting specifies what character encoding is used to decode '%xx'-encoded bytes in path and query of a request URI.

If server is configured with "strict servlet compliance" on, the default value of URIEncoding attribute of connectors is "ISO-8859-1", the same as in older versions of Tomcat.

Reference: HTTP connector, AJP connector.


The handling of digested passwords has been moved to the new CredentialHandler component. The associated Realm attributes will still work in 8.0.x but they have been deprecated and have been removed for Tomcat 8.5.x onwards.

Web application resources

The Aliases, VirtualLoader, VirtualDirContext, JAR resources and external repositories features that all provided a way to add resources to a web application have been replaced with a single framework rather than each being implemented separately (this was becoming increasingly difficult to maintain). The resources documentation provides details on how the new implementation may be used.

The refactoring of resources has also resulted in a number of attributes being removed from the default Context implementation (org.apache.catalina.core.StandardContext). The following attributes may now be configured via the resources implementation used by the web application:

  • allowLinking
  • cachingAllowed
  • cacheMaxSize
  • cacheObjectMaxSize
  • cacheTtl (renamed: it was cacheTTL in Tomcat 7)

For example, configurations in Tomcat 7 and Tomcat 8:

<!-- Tomcat 7: -->
<Context allowLinking="true" />

<!-- Tomcat 8: -->
  <Resources allowLinking="true" />

Database Connection Pooling

Tomcat 8 embeds a packaged renamed version of Apache Commons DBCP 2.x as the default implementation of a database connection pool. There are a number of notable changes between Commons DBCP 1.x (used by Tomcat 7 and earlier) and Commons DBCP 2.x which are likely to require configuration changes.

  • The maxActive configuration option has been renamed to maxTotal
  • The maxWait configuration option has been renamed to maxWaitMillis
  • The JDBC driver JAR may be placed in WEB-INF/lib as an alternative to $CATALINA_BASE/lib provided that the driver class is only used by that web application.
  • Connection validation no longer requires both a validation query and at least one of the testXxx attributes to be set to true. If no validation query is defined and at least one of the testxxx attributes is true, connections will be validated using Connection.isValid().
  • The removeAbandoned configuration option has been replaced by removeAbandonedOnBorrow and removeAbandonedOnMaintenance.

Additionally, Commons DBCP has added a number of new configuration options. These should be reviewed to determine which, if any, should be used.


The addition of the HttpServletRequest.changeSessionId() method in Servlet 3.1 made the org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener unnecessary so it has been removed. It must be removed from cluster configurations when upgrading to Tomcat 8.


When starting Tomcat with the jpda option to enable remote debugging, Tomcat 8 listens on localhost:8000 by default. Earlier versions listened on *:8000. If required, this default can be overridden by setting the JPDA_ADDRESS environment variable in, for example, setenv.[bat|sh].

Internal APIs

Whilst the Tomcat 8 internal API is broadly compatible with Tomcat 7 there have been many changes at the detail level and they are not binary compatible. Developers of custom components that interact with Tomcat's internals should review the JavaDoc for the relevant API.

Of particular note are:

  • The Manager, Loader and Resources have moved from Container to Context since Context is the only place they are used.
  • The Mapper has moved from the Connector to the Service since the Mapper is identical for all Connectors of a given Service.
  • A new Resources implementation that merges Aliases, VirtualLoader, VirtualDirContext, JAR resources and external repositories into a single framework rather than a separate one for each feature.
  • A new interface SessionIdGenerator has been added making session id generation extensible. Methods to get and set the id generator class name have been added to the Manager interface.


Deployment of a web application as a WAR file and with Tomcat configured not to unpack WARs will result in significantly slower startup times and slower runtime performance. Start-up times have been measured between three and ten times slower. Runtime impact will depend significantly on the application structure.

It is strongly recommended not to set unpackWARs="false" on a Host or unpackWAR="false" on a Context. Below is a list of common reasons for disabling unpacking and the recommended alternative for Tomcat 8:

  • Security (appBase is readOnly to Tomcat user) - Deploy (as a different user) an unpacked directory to the appBase rather than a WAR file.
  • Sharing an appBase between multiple hosts - Deploy WAR files to a common location and then use context.xml files to add the web applications to the hosts as required. Note sharing an appBase between multiple hosts is strongly discouraged in all circumstances.
  • Off-line deployment - As of Tomcat 8.0.21, Tomcat will detect when a WAR has been updated while it is not running and, when next started, remove the out of date expanded directory and deploy the updated WAR file so simply use unpackWAR="true" and continue to deploy WARs when Tomcat is not running.

Upgrading 8.0.x

When upgrading instances of Apache Tomcat from one version of Tomcat 8 to another, particularly when using separate locations for $CATALINA_HOME and $CATALINA_BASE, it is necessary to ensure that any changes in the configuration files such as new attributes and changes to defaults are applied as part of the upgrade. To assist with the identification of these changes, the form below may be used to view the differences between the configuration files in different versions of Tomcat 8.

Tomcat 8.0.x noteable changes

The Tomcat developers aim for each patch release to be fully backwards compatible with the previous release. Occasionally, it is necessary to break backwards compatibility in order to fix a bug. In most cases, these changes will go unnoticed. This section lists changes that are not fully backwards compatible and might cause breakage when upgrading.

  • In 8.0.24 onwards, the meaning of value 0 for maxPostSize attribute on connectors was changed to mean a limit of zero rather than no limit to align it with maxSavePostSize and to be more intuitive.

    Reference: HTTP connector, AJP connector.

Tomcat 8.0.x configuration file differences

Select a configuration file, old version and new version from the boxes below and then click "View differences" to see the differences. The differences will be shown in a new tab/window.

You can also use Subversion command similar to the following (all on one line):

svn diff