The Tomcat move: The unexpected which made us think

By Samanth Gunapal – Websites Core Platform team

One of our core products got moved from Weblogic 10.5 to Tomcat 7.0 recently. The older generation of the product was very dependent on a lot of Weblogic application server capabilities like EJBs, clustering, messaging. They were all removed in a planned manner. Once all of that got done, we were in the last leg of the move. When we ran the ported application on Tomcat, we found a lot of unexpected problems related to how things work differently in Tomcat and Weblogic. I would like to share some of the interesting ones, which needed us to make up our mind on how we wanted to handle them.

 

Tag instances are pooled!

One of the first things we noticed that some of our custom tags were broken. When we investigated further, we realized that our tags were getting wrong dependencies. When the tag was used in a particular place, it was getting dependencies from its first usage – dependencies were shared! That’s when we realized that tag instances were pooled in Tomcat and not so in Weblogic. In general, tag pooling seems to be a good practice and it is recommended. However, this didn’t work in our case since we wanted different behavior from the tag based on the different dependencies we provided to it. To give an example,

@Configurable(preConstruction = true)
public class MyTag extends TagSupport {
 @Resource
 private MyDependency dependency; // Depending on different contexts and needs, a different implementation needs to be injected
... 
}
So, we used a workaround to disable pooling by changing $CATALINA_BASE/conf/web.xml.
<servlet>
 <servlet-name>jsp</servlet-name>
 <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
 ...
 <init-param>
  <param-name>enablePooling</param-name>
  <param-value>false</param-value>
 </init-param>
 ...
</servlet>

 

The story of the truncated cookie

We store user preferences in cookies so that we can provide them with a personalized experience. For example, if the user chooses a particular make and model, we store that in a cookie like below.

Name Value Domain
userPreferences make=Chevrolet&model=Camaro http://www.example.com

Once we migrated to tomcat, this started failing. We found that Tomcat doesn’t allow a few characters in cookie values such as white space, brackets, parentheses, equals sign, commas, quotes, question mark etc. unless you explicitly enable it. Here is how the cookie value varies.

//code snippet
System.out.println (cookie.getName() + “ : ” + cookie.getValue());

//output
userPreferences : make=Chevrolet&model=Camaro //In Weblogic
userPreferences : make  //In Tomcat, cookie value got truncated from the character '='
The reason behind this seems that Tomcat by default adheres to version 0 cookie refer here. But since our user preferences were richer in nature and most users are on modern browsers, we decided to keep our richer cookies as is. So, we used the following Tomcat system properties to enable this behavior.
org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE=true
org.apache.tomcat.util.http. ServerCookie.ALLOW_HTTP_SEPARATORS_IN_VALUE=true

 

EL expressions with Java keywords will be stopped!

Few JSPs in our product were broken with javax.el.ELException. When we dug deeper on one of many instances, we found the following snippet in the JSP and the corresponding method in POJO.
//JSP snippet
...
${vehicle.new}
...
//POJO
class Vehicle {
  ...
  public boolean isNew() {
    //returns true if it is a new vehicle.
  }
  ...
}
Weblogic was working fine in this scenario, but Tomcat threw the exception. We then found that Tomcat’s EL parser seems to be stricter than that of Weblogic when it comes to the usage of Java keywords in EL expressions. But in this case, we wanted to preserve the semantics that the method name offered to our domain and code base. So we decided to turn off this check in Tomcat. We achieved the same using the following JVM argument.
-Dorg.apache.el.parser.SKIP_IDENTIFIER_CHECK=true

 

Conclusion

One aspect that jumps at us is that Tomcat seems to be leaning towards being stricter and conservative whereas Weblogic is more lenient and flexible. Generally, such strictness ensures that that the code we write is cleaner and better. That said, the above scenarios illustrate that sometimes it is important to weigh the benefits of following a practice in the context of how it applies to the product.