Using JSTL and context variables

Recently, I wanted to get rid of the Java scriptlets in my jsp and replace it with JSTL tags. The code in question was the Hitbox and Google Analytics scripts that run in our template. I wanted the scripts to show when the code was running in production. I also wanted the scripts to link to a secure url when the page was encrypted.

Its easy to embed Java code within the JSP. But how do you do this using the Expression Language? That was the challenge.

My setup is:
JSP 1.2
Struts 1.2.0
Tomcat 5.5.12

Challenge 1

My first challenge in the conversion was to figure out how to display the code when on the production server. I did this by setting init parameters in the tomcat web.xml file of the server I wanted to load these scripts.

I added the following code to the end of my tomcat’s web.xml file, located in <tomcat>/conf/web.xml:


<!-- ==================== Analytics production flag ===================== -->
<!-- This flag is used in the template jsp's to decide whether to display -->
<!-- the Analytics tracking code. This should only be on the production -->
<!-- server, but can be added to test code when testing. This is to -->
<!-- ensure that we dont log visits when developing. -->
<context-param>
<param-name>hbxIsProduction</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>gaIsProduction</param-name>
<param-value>true</param-value>
</context-param>

Then in my template.jsp file I added the initParam resource and called the hbxIsProduction variable which I set in web.xml.


<c:if test="${initParam.hbxIsProduction == \"true\"}">
//my hbx logic here
</c:if>
<c:if test="${initParam.gaIsProduction == \"true\"}">
//my google logic here
</c:if>

If an init parameter was set to true than the jsp would output the analytics logic. If the params were set to any other value or non-existent, then the comparison failed and output nothing.

Challenge 2

The second challenge I had was to output the link to the google analytics script with http or https depending on whether the page was secure. I was able to achieve this by calling the pageContext and referencing the request value, secure:


<c:if test="${pageContext.request.secure}">
//my secure google url
</c:if>
<c:if test="${!pageContext.request.secure}">
//my unsecure google url
</c:if>

The final version of my template code looked like this:


<c:if test="${initParam.hbxIsProduction == \"true\"}">
<!-- HBX - Call the default variables -->
<script src="<c:url value="/js/hbx/hbx_cfg.js"/>" language="javascript1.1" type="text/javascript"></script>
<!-- HBX - Set global custom variables, ie affiliate, -->
<script type="text/javascript">
hbx.acct="XXXXXXXXXXXXXXXX";//ACCOUNT NUMBER(S)
hbx.hc1="<c:out value="${sessionScope.affiliate}"/>";//CUSTOM 1:Affiliate
</script>
<!-- HBX - Send data -->
<script defer="defer" src="<c:url value="/js/hbx/hbx.js"/>" type="text/javascript"></script>
</c:if>
<c:if test="${initParam.gaIsProduction == \"true\"}">
<!-- GA - call urchin.js file depending on secure page -->
<c:if test="${pageContext.request.secure}">
<script src="https://ssl.google-analytics.com/urchin.js" type="text/javascript"></script>
</c:if>
<c:if test="${!pageContext.request.secure}">
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
</c:if>
<!-- GA - set google account and call tracker -->
<script defer="defer" type="text/javascript">
var _uacct = "XX-XXXXXX-X";
urchinTracker();
</script>
</c:if>

Needless to say, my code looks much cleaner and simpler.

Tomcat/Java java.lang.outofmemory error problem

For about the last 12 months my companies website has been randomly having out of memory errors. We have been completely lost as to why this is happening.

The problem seems to be this. Our website uses sessions to track users. Each session consumes about 30k of memory. Since we have set our session timeout to 180 minutes or 3 hours these sessions remain in memory until then. The other day my boss was running a custom script that analyzes webpages and coincidentally about 11,000 urls relating to pages on our website were being hit. One at a time but thousands per hour. Apparently the default settings of Tomcat allocate 16 megs up to 64 megs of memory. Tomcat would make it for ~25 minutes before crashing with a java.lang.outofmemory error.

I went and looked on Google for any solutions for months, then this week I finally stumbled upon an article that sounded similar to our problem. You can tell Tomcat to start up with Java using a minimum and a maximum amount of memory.

In conclusion we have now fixed our server crashing problem by adding these lines to a batch file that creates the windows service. When Tomcat starts up it allocates itself much more ram than before.

%CATALINA_HOME%\bin\tomcat -install “Jakarta Tomcat 4” %JAVA_HOME%\jre\bin\server\jvm.dll -Djava.class.path=%CATALINA_HOME%\bin\bootstrap.jar;%JAVA_HOME%\lib\tools.jar -Dcatalina.home=%CATALINA_HOME% %CATALINA_OPTS% -Xrs -Xms1024m -Xmx1536m -start org.apache.catalina.startup.Bootstrap -params start -stop org.apache.catalina.startup.Bootstrap -params stop -out e:\logs\tomcat\stdout.log -err e:\logs\tomcat\stderr.log

* Note the use of the -Xms—-m and -Xmx—-m switches.

We run Tomcat 4.1.30 on Windows 2000 servers with 2G of Ram and 2G of Virtual Ram