Wednesday, January 26, 2011

Turned on the Jasper Validation in IntelliJ Idea and facing weird / illogical errors?

So we are in the process of migrating our web application from Resin to Tomcat. The first major problem was that Resin does not use Jasper for compiling the JSP files. So it’s obvious since we were running on Resin ,we had the “Jasper Validation On Build” option in the Idea IDE turned off.

Since Tomcat uses Jasper for its compilation we needed to turn this option on. After doing that what you think happened?? Approx 400 compile issues!!

So we fixed most of the issues and we came down to just 10 errors which were all caused because of a package that could not be resolved. Thinking this was some setting problem we dug through this for nearly 2 days and we nearly pulled our hair out .I say nearly pulled our hair out because Idea IDE was acting weird and completely illogical .We changed the name of the package and it suddenly detected the new package and all the errors disappeared .What was even worse the other packages which was on the same level were getting detected .If we had say “com.rein.test” and “com.rein.newtest” ,the latter was found . “com.rein.test” was physically present but to Idea it just could not find it. Ok let me stop and tell you how we knew it was an IntelliJ Idea issue.

We used Jasper libraries in Tomcat to do the validation and compilation via an ant script and voila it worked .Build Successful !! is what we got. I’ve added the ant script below so that you to don’t go through the same “What the hell is wrong here?” state

// Begin Ant Script

<project name=”JSP Compilation”>
<property name=”tomcathome.dir” location=” “/>
<property name=”webapps.dir” location=” “/>
<target name=”jsp_jasper_compilation”>
<taskdef resource=”org/apache/catalina/ant/catalina.tasks”>
<classpath>
<fileset file=”${ tomcathome.dir}/bin/tomcat-juli.jar”/>
<fileset file=”${ tomcathome.dir}/lib/jasper.jar”/>
<fileset file=”${ tomcathome.dir}/lib/jasper-el.jar”/>
<fileset file=”${ tomcathome.dir}/lib/el-api.jar”/>
<fileset file=”${ tomcathome.dir}/lib/jsp-api.jar”/>
<fileset file=”${ tomcathome.dir}/lib/servlet-api.jar”/>
<fileset file=”${ tomcathome.dir}/lib/catalina-ant.jar”/>
</classpath>
</taskdef>
<jasper uriroot=”${ webapps.dir }”
outputDir=”${webapps.dir }/WEB-INF/compiledJSP” failonerror=”true”/>
</target>
</project>

// End Ant Script

I am not saying don’t use IntelliJ idea to validate your Jsps. But if you ever face weird /illogical errors, don’t break your head but instead try the ant script.
Till next time…

Monday, January 17, 2011

Storing and Sharing Sessions among standalone Tomcat instances

Are you migrating from Resin to Tomcat?

Were you using a database like mysql to store sessions?

Did you configure Resin to <always-load> and <always-save> sessions after each request and trying to figure out if there is a way in Tomcat to configure the same?

Are you trying to figure out how to configure a backup database for High Availability (HA) and Failover?

Well if any one (or all) are applicable to you ...then this post will be very helpful

First things first you need to know and which is clearly mentioned in the docs Persistent Manager (the guy who does all the magic of storing sessions based on the configuration in the server.xml) in Tomcat has not been thoroughly tested, and should be considered experimental!. Some more hard facts which are NOT mentioned in the docs are and which you may have thought were possible:

# Are you trying to configure the Persistent Manager to <always-load> and <always-save> sessions after each request? Well then try no more cause there simply no way "yet". You may read some articles mentioning this is possible by setting maxIdleSwap='0' but it won’t achieve the desired result. The reason being PersistentManagerBase backups all sessions in batches (processMaxIdleSwaps(),processMaxIdleBackups() are called by the background thread). You might try to set maxIdleBackup and maxIdleSwap to 0. But even then sessions are only stored by the background thread (running every 10seconds by default IIRC) and not directly at the end of the request.

# Are you trying to figure out how to configure a backup database for High Availability (HA) and Failover? Well then stop trying. There is no way to configure the Persistent Manager to use a backup database which will be used in case the primary one kicks the bucket.

So whether you are going the sticky sessions or non-sticky sessions way, the Tomcat implementation of a Session Store (Persistent Manager) does not provide a reliable failover / HA solution for standalone instances of Tomcat.

Is there another solution? Well Yes and No.

Yes, if you’re going the Sticky Session approach. http://code.google.com/p/memcached-session-manager/#How_does_it_work? .I also had a conversation with the developer of the memcached-session-manager and he confirmed that it’s very stable and thoroughly tested. They are running www.tchibo.de (and tchibo.ch, tchibo.at etc.) with memcached-session-manager with sticky sessions in production (Tchibo is a German chain of coffee shops and caf├ęs).

No, if you’re going the Non-Sticky approach .There is the memcached-session-manager version for non-sticky sessions https://github.com/magro/memcached-session-manager/tree/nonsticky-sessions. But according Martin Grotzke it’s not for production and still has issues like concurrent session modification,SPOF etc etc.. which still needs to be fixed.

Till next time....

Sticky Sessions Or Non-Sticky Sessions ? Keep this in mind

I had an interesting discussion with Martin Grotzke (the guy creator of the memcached-manager for Tomcat) and during that discussion he raised some good points when configuring standalone instances of tomcat/resin.

In the case of non-sticky sessions, a session is never loaded from the memory of the app server. The session will always have to be loaded from store (in our case a database) for each request. Since the sessions are non-sticky, requests can go to any Resin/Tomcat instance. Concurrent requests can go out from the client’s browser (multiple windows or tabbed-browsing).In such a case some kind of “session locking” needs to be done since multiple requests may access/modify the same session object. There is no clear documentation in Resin if they have implemented any session locking but Tomcat does not have any such session locking when configured as a standalone instance. Period!! .

In the case of sticky-sessions, a request will always go to the same Resin/Tomcat instance ( which the session was first created on).But we still need to handle concurrent requests accessing the same session object. One way this would be achieved is by ensuring we do all the session value modification (setAttributes) in a synchronized block. But we all know it would affect performance when handling multiple concurrent requests.

Till next time…..