Skip to content

Tag Archives: Tomcat

Upgrading to Tomcat 8.0.24


If you upgrade your Tomcat installation to 8.0.24, released on July 6th, and all your POST requests suddenly starts to fail, check


of your connectors.

The Tomcat team actually fixed it’s behavior:

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

The maximum size in bytes of the POST which will be handled by the container FORM URL parameter parsing. The limit can be disabled by setting this attribute to a value less than zero. If not specified, this attribute is set to 2097152 (2 megabytes).

I had a 0 (zero) in it… That means absolutely no post data. If the setting makes sense or not is irrelevant, it’s correct that way. So, if you’re post requests fail and you wanted to disable the maximum post size, set it to -1.

Ah, and by the way, since Tomcat 8 you can drop the spring-instrument-tomcat module and the stanza in context.xml:

<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>

Tomcat 8 supports load-time weaving of aspects out of the box and for me, having that module on the class path and using the Spring provided class loader, weaving didn’t work.

Fixing hibernate “Cannot release connection” exception using DBCP and MySQL.


Every 8 hours i got a Hibernate exception “Cannot release connection” within a Java application using Hibernate, Apache DBCP on Tomcat:

org.hibernate.exception.GenericJDBCException: Cannot release connection
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(
    at org.hibernate.exception.SQLStateConverter.convert(
    at org.hibernate.exception.JDBCExceptionHelper.convert(
    at org.hibernate.exception.JDBCExceptionHelper.convert(
Caused by: java.sql.SQLException: Already closed.

Not only that the messages polluted my inbox, the exception was visible to the enduser, resulting in a HTTP 500 error. An older blog post i found suggested dismissing DBCP and using c3p0, a solution that i’m not quite found of. At least, the post helped to reproduce the problem within my development setup. The underlying problem was indeed the MySQL wait_timeout.

There’s quite a long documentation on the Tomcat JDBC Connection Pool. Although the Tomcat team recommends their own solution since Tomcat 7, i still wanted to go with DBCP.

The relevant keywords are “testOnBorrow”, “testOnReturn”, “testWhileIdle”, “validationQuery” and “timeBetweenEvictionRunsMillis”. The first 3 are boolean values. If set to true, the query given as validationQuery is executed on borrowing a connection from the pool, on returning or when idling. The first option is not an option on production use as the query is executed before each call. Although “Select 1″ is probably very fast, i just don’t want to have. Also: The problem is an invalidated, idle connection so i set testWhileIdle to true. And what happened? Nothing! The problem stayed. So there is the last option timeBetweenEvictionRunsMillis which should, according to the docs, default to 5 seconds but it doesn’t. The documentation is wrong. It’s under zero, so the eviction thread that tests idle connections never run. I’ve tweeted the tomcat team, but there was no reaction.

So the correct configuration for a DBCP pool database source is:

	validationQuery="Select 1"

This way the eviction thread runs every 30 minutes, testing idle connections with the query “Select 1″ and removing them from the pool. The timeBetweenEvictionRunsMillis should not be to low. It should be adapted to the configured MySQL wait_timeout.

Apache httpd, Tomcat und sendfile


I used to use mod_xsendfile by Nils Maier, who’s Homepage doesn’t seem to exist anymore, to send files from Ruby proxied by Apache respectively powered by modrails. Those files shouldn’t be in any public www directory as authorization needs to be checked, but are accessed very often so that streaming them is not an option.

To use this technique you need mod_xsendfile, which is attached to this post.

I just have rewritten my application from Ruby on Rails to Java and it’s easy to add the necessary headers in a HttpServletResponse:

response.setHeader("X-Sendfile", file.getAbsolutePath());

You may add other headers like Content-Type and the like but you must not modify the body, hence the flushBuffer.

This works quite well… As long as had my Apache httpd running with mpm-prefork.

Switching to Apache mpm-worker caused some problems. I cannot say with a final conclusion that mod_xsendfile was causing troubles but i started to see the wrong files (images in this case) delivered or not delivered at all.

My alternate solution was streaming the files using Channels from java.nio but CPU usage went nuts.

The solution now employed is the using Apache Tomcats asynchronous writes that are available since Tomcat 6. Their documentation is rather short but so is implementing them:

HttpServletRequest request = ...
HttpServletResponse response = ...
if(request != null && Boolean.TRUE.equals(request.getAttribute(""))) {		
  long l = file.length();
  request.setAttribute("org.apache.tomcat.sendfile.filename", absolutePath);
  request.setAttribute("org.apache.tomcat.sendfile.start", 0l);
  request.setAttribute("org.apache.tomcat.sendfile.end", l);
  response.setHeader("Content-Length", Long.toString(l));
} else if(use_xsendfile) {
  // see above
} else {
  // stream files

What i got wrong at first was setting those attributes in the response. That didn’t work. The must be set in the request and you must take care setting all of those and with the correct type (String respectively long). And that’s it.

The request attribute will be true when the connector is configured to either use the APR connector (org.apache.coyote.http11.Http11AprProtocol) or the non blocking Java connector (org.apache.coyote.http11.Http11NioProtocol) (the later one being easier to deploy as it has no external dependencies).

CPU usage for sending those files is now nearly 0.

Disable jsessionid path parameter in Java web applications


Wow, this has driven me nuts…

Most J2EE developers will know the ugly-as-hell ;jsessionid=BLAHBLAHBLAH appended as a path parameter to all urls of an application on the first call of a page that creates a session.

Tomcat as of version 6 has the possibility to add the attribute ‘disableURLRewriting=”true”‘ to the context of the application but that didn’t work for me…

The problem was: I’m using Spring Security and Spring Security has it’s own mechanism and control for the session store.

It can be disabled through security-conf.xml (or wherever you’ve stored the Spring Security configuration) within the http element:

<http use-expressions="true" disable-url-rewriting="true" create-session="ifRequired">

And boom, the path parameter is gone.

For more information see The Security Namespace

The jsession parameter is used on the first page that requires a session as the server cannot now at this point in time whether the client supports cookies or not. If you disable it, you’re clients need to allow cookies, otherwise no session will be created.

Different day, same shit, today: Java 5 on Oracle Enterprise Linux 5


Worlds collide: Oracle and Sun JDK. Perfect start to ruin a not so bad Monday morning.

Background: Need to have a Tomcat Server deployed on a Oracle Enterprise Linux 5 system.

I was happy, when i saw a tomcat5 package in the repositories. Great, i thought. All i need. Well. Not.

Under Windows you’ll get between one and ten JVM versions installed with on Oracle product (slight exaggerated), within the OEL5 there was only one ancient 1.4.2 JDK. *sigh* Did i mention that the application that is supposed to run on that thing uses a buttload of Java 5 features?

“yum search java-“… No Java 5. WtF?

There is no Java 5.

Again, do it yourself:

This is a nice entry that describes howto build rpms for the “official” Sun Java 5 jdk.

I used the following steps to build my rpms:

  • Downloaded this rpm
  • Downloaded jdk-1_5_0_15-linux-i586.bin from the Sun JDK archive page
  • Put the later one into /usr/src/redhat/SOURCES/
  • Built the rpms with rpmbuild –rebuild java-1.5.0-sun- If rpmbuild is not installed, it’s hidden in the package rpm-build, not rpmbuild.
  • Installed missing libXp
  • Installed the rpms:
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-devel-
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-src-
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-demo-
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-plugin-
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-fonts-
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-alsa-
    rpm -Uvh /usr/src/redhat/RPMS/i586/java-1.5.0-sun-jdbc-
  • Last step: Choose the right java version with alternatives –config java

After that, everything could be fine. Well, it wasn’t:

sun.misc.InvalidJarIndexException: Invalid index

Jehova! Finally not a NPE but something new, at least to me. Sometimes i wonder why i always run into bugs like these.

Some script changes and repackages all jar files in some weird ways so that a standard JDK has funny problems.

My solution to it: Reindex everything in /usr/share/java after you’ve chosen your newly installed java with the following command:

find /usr/share/java/ -iname "jakarta*commons*.jar" -exec jar -i {} \;

I opted to reindex only the jakarta commons files, that got Tomcat up and running with Java 5.

One last note: The /usr/bin/dtomcat5 is broken imho, at least when run from /etc/init.d/tomcat5. In ignores /etc/tomcat5/tomcat5.conf and therefore cannot stop Tomcat.

My solution: Replace

if [ -z "$CATALINA_HOME" ]; then

(in line 55 on my setup) with

if [ -z "$CATALINA_HOME" ]; then
    [ -r "$TOMCAT_CFG" ] && . "${TOMCAT_CFG}"

and remove

if [ -z "$CATALINA_HOME" ]; then
    [ -r "$TOMCAT_CFG" ] && . "${TOMCAT_CFG}"

(in line 105 on my setup).

I wonder why simple things like these always are a pain in the ass. Stupid nuisances that keeps people from getting their work done. *sigh* Not a good start for the week.