The Apache Tomcat Servlet/JSP Container

Apache Tomcat 7

Version 7.0.65, Oct 9 2015
Apache Logo

Links

User Guide

Reference

Apache Tomcat Development

Changelog

Tomcat 7.0.65 (violetagg)
Catalina
add 57681: Add a web application class loader implementation that supports the parallel loading of web application classes. Use of this feature requires a Java 7 or later JRE. Based on a patch by Huxing Zhang. (markt)
fix 58187: Correct a regression in the fix for 57765 that meant that deployment of web applications deployed via the Manager application was delayed until the next execution of the automatic deployment background process. (markt)
fix 58284: Correctly implement session serialization so non-serializable attributes are skipped with a warning. Patch provided by Andrew Shore. (markt)
fix 58313: Fix concurrent access of encoders map when clearing encoders prior to switch to async. (markt)
fix 58320: Fix concurrent access of request attributes which is possible during asynchronous processing. (markt)
code In preparation for implementing enhancement 57681, replace the use of the StandardClassLoader with URLClassLoader. This removes the server class loader from JMX. (markt)
fix 58352: Always trigger a thread dump if Tomcat fails to stop gracefully from catalina.sh even if using -force. Patch provided by Alexandre Garnier. (markt)
fix 58416: Correctly detect when a forced stop fails to stop Tomcat because the Tomcat process is waiting on some system call or is uninterruptible. (markt)
fix 58436: Fix some rare data races in JULI's ClassLoaderLogManager during shutdown. (markt)
Coyote
fix Correct some edge cases in RequestUtil.normalize(). (markt)
fix 58275: The IBM JREs accept cipher suite names starting with TLS_ or SSL_ but when listing the supported cipher suites only the SSL_ version is reported. This can break Tomcat's check that at least one requested cipher suite is supported. Tomcat now includes a work-around so either form of the cipher suite name can be used when running on an IBM JRE. (markt)
fix 58357: For reasons not currently understood when the APR/native connector is used with OpenSSL reads can return an error code when there is no apparent error. This was work-around for HTTP upgrade connections by treating this as EAGAIN. The same fix has now been applied to the standard HTTP connector. (markt)
fix 57799: Remove useless sendfile check for NIO SSL. (remm)
Jasper
fix 57136: Correct a regression in the previous fix for this issue. \${ should only an escape for ${ within an EL expression. Within a JSP page \$ should be an escape for $. The EL specification applies when parsing the expression delimited by ${ and }. Parsing of the delimiting ${ and } is the responsibility of the JSP specification. (markt)
fix 58296: Fix a memory leak in the JSP unloading feature that meant that using a value other than -1 for maxLoadedJsps triggered a memory leak once the limit was reached. (markt)
fix 58340: Improve error reporting for tag files packaged in JARs. (markt)
fix 58444: Ensure that JSPs work with any custom base class that meets the requirements defined in the JSP specification without requiring that base class to implement Tomcat specific code. (markt)
Cluster
fix Fix a default clusterListeners in SimpleTcpCluster. The optimal default value is different for each session manager. ClusterSessionListener is never used in BackupManager. (kfujino)
fix Correct log messages in case of using BackupManager. (kfujino)
WebSocket
fix 58342: Fix a copy and paste error that meant MessageHandler removal could fail for binary and pong MessageHandlers. Patch provided by DJ. (markt)
fix 58414: Correctly handle sending zero length messages when using per message deflate. (markt)
Web applications
fix Correct documentation for cluster-howto. (kfujino)
Extras
fix Ensure JULI adapters does not include the LogFactoryImpl class. Patch provided by Benjamin Gandon. (markt)
Tribes
add Add support for configurations of ChannelListener and MembershipListener in server.xml. (kfujino)
fix Correct log messages in case of using ReplicatedMap. (kfujino)
jdbc-pool
fix Make sure the pool has been properly configured when attributes that related to the pool size are changed via JMX. (kfujino)
Tomcat 7.0.64 (violetagg)released 2015-08-25
Catalina
add 55317: Facilitate weaving by allowing ClassFileTransformer to be added to WebappClassLoader. Patch by Nick Williams. (markt)
fix 58031: Make the (first) reason parameter parsing failed available as a request attribute and then use it to provide a better status code via the FailedRequstFilter (if configured). (markt)
fix 58086: Ensure that WAR URLs are handled properly when using Apache Ant for web application deployment. (violetagg)
fix 58094: Fix cosmetic error log when using non standard non cacheable resources, like with the empty resources used in some tests. (remm)
fix 58096: Classes loaded from /WEB-INF/classes/ should use that directory as their code base. (markt)
fix Fix possible resource leaks by closing streams properly. Issues reported by Coverity Scan. (violetagg)
fix 58116: Fix a regression in the fix for 57281 that broke Comet support when running under a security manager. Based on a patch provided by Johno Crawford. (markt)
fix 58179: Fix a thread safety issues that could mean concurrent threads setting the same attribute on a ServletContext could both see null as the old value. (markt)
fix 58192: Correct a regression in the previous fix for 58023. Ensure that classes are associated with their manifest even if the class file is first read (and cached) without the manifest. (markt)
fix Fix thread safety issue in the AsyncContext implementation that meant a sequence of start();dispatch(); calls using non-container threads could result in a previous dispatch interfering with a subsequent start. (markt)
Coyote
fix 57943: Prevent the same socket being added to the cache twice. Patch based on analysis by Ian Luo / Sun Qi. (markt)
fix Add text/javascript,application/javascript to the default list of compressable MIME types. (violetagg)
fix 58103: When pipelining requests, and the previous request was an async request, ensure that the socket is removed from the waiting requests so that the async timeout thread doesn't process it during the next request. (markt)
fix Fix a concurrency issue that meant that a change in socket timeout (e.g. when switching to asynchronous I/O) did not always take effect immediately. (markt)
fix In the AJP and HTTP NIO connectors, ensure that the socket timeout is correctly set before adding the socket back to the poller for read. (markt)
fix 58157: Ensure that the handling of async timeouts does not result in an unnecessary dispatch to a container thread that could result in the current socket being added to the Poller multiple times with multiple attempts to process the same event for the same socket. (markt)
fix Correct a couple of edge cases in RequestUtil.normalize(). (markt)
Jasper
fix 58110: Like scriptlet sections, declaration sections of JSP pages have a one-to-one mapping of lines to the generated .java file. Use this information to provide more accurate error messages if a compilation error occurs in a declaration section. (markt)
fix 58119: When tags are compiled they must be placed in the org/apache/jsp/tag/web directory. Correct a regression in the fix for 52725. (violetagg)
fix 58178: Expressions in a tag file should use the tag file's PageContext rather than that of the containing page. (markt)
WebSocket
fix 58166: Allow applications to send close codes in the range 3000-4999 inclusive. (markt)
fix 58232: Avoid possible NPE when adding endpoints programmatically to the javax.websocket.server.ServerContainer. Based on a patch provided by bastian.(violetagg)
Web applications
fix Correct the incorrect document of QueryTimeoutInterceptor. The setting value is not in milliseconds but in seconds. (kfujino)
fix 58112: Update the documentation for using the Catalina tasks in an Apache Ant build file. (markt)
fix Improve the Javadoc for some of the APR socket read functions that have inconsistent behaviour for return values. (markt)
add 58255: Document the Semaphore valve. Patch provided by Kyohei Nakamura. (markt)
jdbc-pool
fix Fix potential NPE in QueryTimeoutInterceptor. (kfujino)
fix Add support for stopping the pool cleaner via JMX. (kfujino)
fix The fairness attribute and ignoreExceptionOnPreLoad attribute do not allow a change via JMX. (kfujino)
fix If the timeBetweenEvictionRunsMillis attribute is changed via jmx, it should restart the pool cleaner because this attribute affects the execution interval of the pool cleaner. (kfujino)
fix Eliminate the dependence on maxActive of busy queues and idle queue in order to enable the expansion of the pool size via JMX. (kfujino)
Other
fix Update sample Eclipse IDE configuration to exclude test/webapp* and similar paths from compiler sourcepath. (kkolinko)
Tomcat 7.0.63 (violetagg)released 2015-07-06
Catalina
fix 57938: Correctly handle empty form fields when a form is submitted as multipart/form-data, the maxPostSize attribute of the Connector has been set to a negative value and the Context has been configured with a value of true for allowCasualMultipartParsing. The meaning of the value zero for the maxPostSize has also been changed to mean a limit of zero rather than no limit to align it with maxSavePostSize and to be more intuitive. (markt)
add 54618: Add a new HttpHeaderSecurityFilter that adds the Strict-Transport-Security, X-Frame-Options and X-Content-Type-Options HTTP headers to the response. (markt)
fix Add a workaround for issues with SPNEGO authentication when running on Java 8 update 40 and later. The workaround should be safe for earlier Java versions but it can be disabled with the applyJava8u40Fix attribute of the SPNEGO authenticator if necessary. (markt)
add 57154: Add support for web applications (Context elements) that do not have a docBase. This is primarily for use when embedding but it also fixes a rare issue when running the unit test. Patch provided by Huxing Zhang. (markt)
fix 57959: Fixed deadlock in org.apache.juli.FileHandler when log is rotated. (violetagg)
fix 57977: Correctly bind and unbind the web application class loader during execution of the PersistentValve. (markt)
fix 58023: Fix potentially excessive memory usage due to unnecessary caching of JAR manifests in the web application class loader. (markt)
fix 57700: Ensure that Container event ADD_CHILD_EVENT will be sent in all cases. (violetagg)
fix Add configuration fields for header names in SSLValve. (remm)
Coyote
fix 57265: Further fix to address a potential threading issue for NIO when sendfile is used in conjunction with TLS. (markt)
fix 57931: Ensure that TLS connections with the NIO HTTP connector that experience issues during the handshake (e.g. missing or invalid client certificate) are closed cleanly and that the client receives the correct error code rather than simply closing the connection. (markt)
add 57943: Added a work-around to catch ConcurrentModificationExceptions during Poller timeout processing that were causing the Poller thread to stop. The root cause of these exceptions is currently unknown. (markt)
fix Fix possible very long (1000 seconds) timeout with APR/native connector. (markt)
add Support "-" separator in the SSLProtocol configuration of the APR/native connector for protocol exclusion. (rjung)
Cluster
fix Make sure that stream is closed after using it in DeltaSession.applyDiff(). (kfujino)
WebSocket
add 57676: List conflicting WebSocket endpoint classes when there is a path conflict. Based upon a patch proposed by yangkun. (schultz)
add Extend support for the permessage-deflate extension to the client implementation.
fix 57969: Provide path parameters to POJO via per session javax.websocket.server.ServerEndpointConfig as they vary between different requests. (violetagg)
fix 57974: Session.getOpenSessions should return all sessions associated with a given endpoint instance, rather than all sessions from the endpoint class. (remm)
Web applications
fix 57282: Update request processing sequence diagrams. Updated diagrams provided by Stephen Chen. (markt)
fix 57971: Correct the documentation for the cluster configuration setting recoverySleepTime. (markt)
add 57758: Add document of testOnConnect attribute in jdbc-pool doc. (kfujino)
add Add description of validatorClassName attribute to testXXXX attributes in jdbc-pool docs. (kfujino)
Tribes
fix Ensure that the state transfer flag is updated to true only when the map states have been transferred correctly from existing map members. (kfujino)
fix Do not set the nodes that failed to replication to the backup nodes. Ensure that the nodes that the data has been successfully replicated are set to the backup node. (kfujino)
fix When failed to replication, rather than all member is handled as a failed member, exclude the failure members from backup members. (kfujino)
jdbc-pool
fix Refactoring of the removeOldest method in SlowQueryReport to behave as expected. (kfujino)
fix 57783: Fix NullPointerException in SlowQueryReport. To avoid this NPE, Refactor SlowQueryReport#removeOldest and handle the abandoned connection properly. (kfujino)
Other
update Update package renamed Apache Commons BCEL to r1682271 to pick up some some code clean up. (markt)
update Update package renamed Apache Commons File upload to r1682322 to pick up the post 1.3.1 fixes. (markt)
update Update package renamed Apache Commons Codec to r1682326. No functional changes. Javadoc only. (markt)
Tomcat 7.0.62 (violetagg)released 2015-05-14
Catalina
add Allow logging of the remote port in the access log using the format pattern %{remote}p. (rjung)
fix 57765: When checking last modified times as part of the automatic deployment process, account for the fact that File.lastModified() has a resolution of one second to ensure that if a file has been modified within the last second, the latest version of the file is always used. Note that a side-effect of this change is that files with modification times in the future are treated as if they are unmodified. (markt)
fix Align redeploy resource modification checking with reload modification checking so that now, in both cases, a change in modification time rather than an increase in modification time is used to determine if the resource has changed. (markt)
fix Cleanup o.a.tomcat.util.digester.Digester from debug messages that do not give any valuable information. Patch provided by Polina Genova. (violetagg)
fix 57772: When reloading a web application and a directory representing an expanded WAR needs to be deleted, delete the directory after the web application has been stopped rather than before to avoid potential ClassNotFoundExceptions. (markt)
fix 57801: Improve the error message in the start script in case the PID read from the PID file is already owned by a process. (rjung)
fix 57824: Correct a regression in the fix for 57252 that broke request listeners for non-async requests that triggered an error that was handled by the ErrorReportingValve. (markt/violetagg)
fix 57841: Improve error logging during web application start. (markt)
fix 57856: Ensure that any scheme/port changes implemented by the RemoteIpFilter also affect HttpServletResponse.sendRedirect(). (markt)
fix 57896: Support defensive copying of "cookie" header so that unescaping double quotes in a cookie value does not corrupt original value of "cookie" header. This is an opt-in feature, enabled by org.apache.tomcat.util.http.ServerCookie.PRESERVE_COOKIE_HEADER system property. (kkolinko)
Coyote
fix 57779: When an I/O error occurs on a non-container thread only dispatch to a container thread to handle the error if using Servlet 3+ asynchronous processing. This avoids potential deadlocks if an application is performing I/O on a non-container thread without using the Servlet 3+ asynchronous API. (markt)
fix 57833: When using JKS based keystores for NIO, ensure that the key alias is always converted to lower case since that is what JKS key stores expect. Based on a patch by Santosh Giri Govind M. (markt)
fix 57837: Add text/css to the default list of compressable MIME types. (markt)
Jasper
fix 57845: Ensure that, if the same JSP is accessed directly and via a <jsp-file> declaration in web.xml, updates to the JSP are visible (subject to the normal rules on re-compilation) regardless of how the JSP is accessed. (markt)
fix 57855: Explicitly handle the case where a MethodExpression is invoked with null or the wrong number of parameters. Rather than failing with an ArrayIndexOutOfBoundsException or a NullPointerException throw an IllegalArgumentException with a useful error message. (markt)
Cluster
add Add new attribute that send all actions for session across Tomcat cluster nodes. (kfujino)
fix Remove unused pathname attribute in mbean definition of BackupManager. (kfujino)
fix 57338: Improve the ability of the ClusterSingleSignOn valve to handle nodes being added and removed from the Cluster at run time. (markt)
fix Avoid unnecessary call of DeltaRequest.addSessionListener() in non-primary nodes. (kfujino)
WebSocket
fix 57762: Ensure that the WebSocket client correctly detects when the connection to the server is dropped. (markt)
fix 57776: Revert the 8.0.21 fix for the permessage-deflate implementation and incorrect op-codes since the fix was unnecessary (the bug only affected trunk) and the fix broke rather than fixed permessage-deflate if an uncompressed message was converted into more than one compressed message. (markt)
fix Fix log name typo in WsRemoteEndpointImplServer class, caused by a copy-paste. (markt/kkolinko)
fix 57788: Avoid NPE when looking up a class hierarchy without finding anything. (remm)
Web applications
add 57759: Add information to the keyAlias documentation to make it clear that the order keys are read from the keystore is implementation dependent. (markt)
fix 57864: Update the documentation web application to make it clearer that hex values are not valid for cluster send options. Based on a patch by Kyohei Nakamura. (markt)
Tribes
fix Fix a concurrency issue when a backup message that has all session data and a backup message that has diff data are processing at the same time. This fix ensures that MapOwner is set to ReplicatedMapEntry. (kfujino)
fix Clarify the handling of Copy message and Copy nodes. (kfujino)
fix Copy node does not need to send the entry data. It is enough to send only the node information of the entry. (kfujino)
fix ReplicatedMap should send the Copy message when replicating. (kfujino)
fix Fix behavior of ReplicatedMap when member has disappeared. If map entry is primary, rebuild the backup members. If primary node of map entry has disappeared, backup node is promoted to primary. (kfujino)
fix When a map member has been added to ReplicatedMap, make sure to add it to backup nodes list of all other members. (kfujino)
Tomcat 7.0.61 (violetagg)released 2015-04-07
Catalina
fix 55988: Correct the check used for Java 8 JSSE server-preferred TLS cipher suite ordering. Ensure that SSL parameters are provided to SSLServerSocket and SSLEngine. Patch provided by Ognjen Blagojevic. (violetagg)
WebSocket
fix 57761: Ensure that the opening HTTP request is correctly formatted when the WebSocket client connects to a server root. (remm)
Tomcat 7.0.60 (violetagg)not released
Catalina
fix Clarify threaded usage of variables by removing volatile marker in NonceInfo. Issue reported by Coverity Scan. (fschumacher)
add 49785: Enable StartTLS connections for JNDIRealm. (fschumacher)
fix 55988: Add support for Java 8 JSSE server-preferred TLS cipher suite ordering. This feature requires Java 8 and is controlled by useServerCipherSuitesOrder attribute on an HTTP connector. Based upon patches provided by Ognjen Blagojevic. (schultz)
add 56438: Add logging that reports when a JAR is scanned for TLDs but nothing is found so that Tomcat may be configured to skip this JAR in future. Based on a patch by VIN. (markt)
fix 56848: Use Locale.forLanguageTag to process Locale headers when running on a Java 7 or later JRE. (markt)
add 57021: Improve logging in AprLifecycleListener and jni.Library when Tomcat-Native DLL fails to load. Based on a patch by Pravallika Peddi. (markt/kkolinko)
fix 57180: Further fixes to support the use of arbitrary HTTP methods with the CORS filter. (markt)
add Warn about problematic setting of appBase. (fschumacher)
fix 57534: CORS Filter should only look at media type component of Content-Type request header. (markt)
fix Ensure that user name checking in the optional SecurityListener is case-insensitive (as documented) and than the case-insensitive comparison is performed using the system default Locale. (markt)
fix When docBase refers internal war and unpackWARs is set to false, avoid registration of the invalid redeploy resource that has been added ".war" extension in duplicate. (kfujino)
fix If WAR exists, it is not necessary to trigger a reload when adding a Directory. (kfujino)
fix 56608: When deploying an external WAR, add watched resources in the expanded directory based on whether the expanded directory is expected to exist rather than if it does exist.
fix When triggering a reload due to a modified watched resource, ensure that multiple changed watched resources only trigger one reload rather than a series of reloads.
fix 57601: Ensure that HEAD requests return the correct content length (i.e. the same as for a GET) when the requested resource includes a resource served by the Default servlet. (jboynes/markt)
fix 57602: Ensure that HEAD requests return the correct content length (i.e. the same as for a GET) when the requested resource includes a resource served by a servlet that extends HttpServlet. (markt)
fix 57621: When an async request completes, ensure that any remaining request body data is swallowed. (markt)
fix 57637: Do not create unnecessary sessions when using PersistentValve. (jboynes/fschumacher)
fix 57645: Correct a regression in the fix for 57190 that incorrectly required the path passed to ServletContext.getContext(String) to be an exact match to a path to an existing context. (markt)
fix Make sure that unpackWAR attribute of Context is handled correctly in HostConfig. (kfujino)
fix When deploying a WAR file that contains a context.xml file and unpackWARs is false ignore any context.xml file that may exist in an expanded directory associated with the WAR. (markt)
fix 57675: Correctly quote strings when using the extended access log. (markt)
fix 57704: Fix potential NPEs during web application start/stop when org.apache.tomcat.InstanceManager is not initialized. (violetagg)
fix Add support for LAST_ACCESS_AT_START system property to SingleSignOn. (kfujino)
fix 57723: Ensure that the Context name and path remain consistent when adding a web application to an embedded Tomcat instance via Tomcat.addWebapp(Host,String,String,String). (markt)
fix 57724: Handle the case in the CORS filter where a user agent includes an origin header for a non-CORS request. (markt)
code Refactor Authenticator implementations to reduce code duplication. (markt)
fix When searching for SCIs o.a.catalina.Context.getParentClassLoader will be used instead of java.lang.ClassLoader.getParent. Thus one can provide the correct parent class loader when running embedded Tomcat in other environments such as OSGi. (violetagg)
Coyote
fix 57509: Improve length check when writing HTTP/1.1 response headers: reserve space for 4 extra bytes. (kkolinko)
add 57540: Make TLS/SSL protocol available in a new request attribute (org.apache.tomcat.util.net.secure_protocol_version). (Note that AJP connectors will require mod_jk 1.2.41 or later, or an as-yet-unknown version of mod_proxy_ajp, or configure the proxy to send the AJP_SSL_PROTOCOL request attribute to Tomcat. Please see the bug comments for details.) Based upon a patch provided by Ralf Hauser. (schultz)
fix 57544: Fix potential infinite loop when preparing a kept alive HTTP connection for the next request. (markt)
fix 57546: Ensure that a dropped network connection does not leave references to the UpgradeProcessor associated with the connection in memory. (markt)
fix 57570: Make the processing of trailer headers with chunked input optional and disabled by default. (markt)
fix When applying the maxSwallowSize limit to a connection read that many bytes first before closing the connection to give the client a chance to read the response. (markt)
fix Prevent an async timeout being processed multiple times for the same socket when running on slow and/or heavily loaded systems. (markt)
fix 57581: Change statistics byte counter in coyote Request object to be long to allow values above 2Gb. (kkolinko)
fix Fix a concurrency issue in the APR Poller that meant it was possible under low load for a socket queued to be added to the Poller not to be added for 10 seconds. (markt)
fix 57638: Avoid an IllegalArgumentException when an AJP request body chunk larger than the socket read buffer is being read. This typically requires a larger than default AJP packetSize. (markt)
fix 57674: Avoid a BufferOverflowException when an AJP response body chunk larger than the socket write buffer is being written. This typically requires a larger than default AJP packetSize. (markt)
code Refactor Connector authentication (only used by AJP) into a separate method. (markt)
add 57708: Implement a new feature for AJP connectors - Tomcat Authorization. If the new tomcatAuthorization attribute is set to true (it is disabled by default) Tomcat will take an authenticated user name from the AJP protocol and use the appropriate Realm for the request to authorize (i.e. add roles) to that user. (markt)
fix Fix an issue that meant that any pipe-lined data read by Tomcat before an asynchronous request completed was lost during the completion of the asynchronous request. This mean that the pipe-lined request(s) would be lost and/or corrupted. (markt)
update Update the minimum recommended version of the Tomcat Native library (if used) to 1.1.33. (markt)
Jasper
fix 57136: Ensure only \${ and \#{ are treated as escapes for ${ and #{ rather than \$ and \# being treated as escapes for $ and # when processing literal expressions in expression language. (markt)
fix 57148: When coercing an object to a given type and a PropertyEditor has been registered for the type correctly coerce the empty string to null if the PropertyEditor throws an exception. (kkolinko/markt)
fix Simplify code in ProtectedFunctionMapper class of Jasper runtime. (kkolinko)
update 57123: Update all references to the ECJ compiler to version 4.4.1. With thanks to Ralph Schaer for uploading the 4.4.1 JAR to Maven Central. (markt)
update 57662: Update all references to the ECJ compiler to version 4.4.2. (violetagg)
fix 57643: Fix JspC when the path to the web application to compile contains a character that must be encoded when used in a URL such as space. (mark)
Cluster
fix Remove unnecessary method that always returns true. The domain filtering works on DomainFilterInterceptor. (kfujino)
WebSocket
fix Correct a bug in the permessage-deflate implementation that meant that the incorrect op-codes were used if an uncompressed message was converted into more than one compressed message. (markt)
Web applications
fix Fix possible resource leaks by closing streams properly. Issues reported by Coverity Scan. (fschumacher)
fix 56058: Add links to the AccessLogValve documentation for configuring reverse proxies and/or Tomcat to ensure that the desired information is used entered in the access log when Tomcat is running behind a reverse proxy. (markt)
fix 57503: Make clear that the JULI integration for log4j only works with log4j 1.2.x. (markt)
fix Remove incorrect note from context configuration page in the documentation web application that stated WAR files located outside the appBase were never unpacked. (markt)
update 57644: Update examples to use Apache Standard Taglib 1.2.5. (jboynes)
fix 57683: Ensure that if a client aborts their connection to the stock ticker example (the only way a client can disconnect), the example continues to work for existing and new clients. (markt)
fix Correct the documentation for deployOnStartup to make clear that if a WAR file is updated while Tomcat is