random technical thoughts from the Nominet technical team

Moving from Velocity to FreeMarker

1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 4.5 out of 5)
Loading ... Loading ...
Posted by matt on Jun 29th, 2005

I recently moved my current web front-end project from rendering views with the Velocity templating engine to use FreeMarker. This entry describes some of the reasons why I chose to make this move.

The main reason I find Velocity annoying is that it does not address - within its core functionality - the most common tasks faced by a template author. This does not mean that these tasks cannot be achieved but it does mean that they are often difficult to achieve, require work-arounds or extra tools or are simply overly verbose for such common tasks. Some specific examples include:

  • Formatting dates
  • Formatting numbers
  • Formatting currency
  • Detecting whether a variable exists in the template model (in other words, that it is not null)
  • Providing the value of a template variable if it exists, or a specified default value if it doesn’t.
    This is simply an ‘if/else’ statement but one that is performed so often in templates - freemarker achieves this using the syntax ${myVar?default('default text')}
  • URL and HTML escaping

The first three formatting issues are interesting since processing text for human consumption will, particularly in a business environment, often involve dates, numbers and currency (web pages for an online shop and their confirmation emails, stock reports etc.) Not having built in support for detecting and dealing with null values is just plain weird. A related gotcha that has fooled me a number of times is that assignments in Velocity are completely ignored if the right hand side evaluates to null - which can produce havoc in loops, as the variable on the left hand side remains at the value used in the previous iteration.

Template Language Syntax

I also find that the FreeMarker syntax is far more appealing. Every statement is properly delimited - and therefore works predictably. I seem to be constantly tracking down odd parsing errors with Velocity. Consider the following fragment in Velocity:

#if( $variableIsTrue )something#elsesomething else#end

This layout is often required due to white-space handling, however not only is it difficult to read, but it will not work as expected either. The Velocity documentation says that the following should be allowed:

#if( $variableIsTrue )something#{else}something else#{end}

But whenever I try it, I get a parse-error for that too. In FreeMarker you can write the following - and it always works as expected:

<#if variableIsTrue>something<#else>something else</#if>

Array Support

Within templates, one often needs to iterate through the contents of a list of some sort. This may be an array or an ArrayList for example. The template author doesn’t necessarily know or care what the underlying implementation of the list is. In Velocity, if it is an ArrayList then you may find out how many elements are contained within using $myList.size() - however you cannot determine the length of an array without installing extra tools. If you’re using Freemarker then whether it’s an ArrayList or an array you can still access the number of elements consistently using myList?size.

Name Spaces

Both Velocity and FreeMarker support the notion of macros. These are extremely handy for defining chunks of text that will be reused multiple times making templates more maintainable and easier to read. FreeMarker supports name spaces for macro libraries so that variables and macro names do not interfere with each other. Whilst using Spring Framework and Velocity, the variable $status often contains Spring macro related values - so I can’t use this variable name for other purposes or worse still if I do, it will have unpredictable results. However, in FreeMarker I import the Spring macro library under the name-space ’spring’ so that the variable spring.status is completely different from the variable status outside of the Spring macro definitions.

FreeMarker Problems

FreeMarker has proved to be much more suited than Velocity to its role of text processing. FreeMarker is not without its own problems, though I have only found one so far. When putting a HashMap object into the template model, it is not possible to pull out objects from it if the key is not a string. The Spring framework macros that create drop-down lists (HTML <select> elements) use a HashMap for the entries in the list - it is often useful to have numeric keys for these entries, especially when having a database generated list where the primary-keys can be used to index the HashMap.

Non-Java Templating Technologies

As an aside, two non-Java related templating systems that I think are excellent are Template Toolkit for Perl and Smarty for PHP.

Implement IronPort servers for anti-spam

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...
Posted by jay on Jun 27th, 2005

We recently completed the installation of a pair of IronPort C30 servers and these are now filtering out almost all spam, as we expected them to do after our evaluation. The IronPorts come as 2U appliances, with all the software pre-installed. They are actually Dell servers underneath as we found out when the impressive looking bezel fell off one. Most visitors to our computer room notice them straight away.

The IronPorts come with two different anti-spam systems:

The first of these is the excellent Brightmail anti-spam system, which is a signature and heuristic content filter. Brightmail is now owned by Symantec so there is always the possibility that some marketing person will ruin it, but so far it seems to be unaffected. The Brightmail service seems to be pretty efficient, we have had no false positives so far and not that much seems to get past it. I don’t have any stats yet on just how much we think it misses but anecdotaly it appears to be just a few messages per person per day.

As we run Lotus Notes we have installed the Brightmail plugin for Notes that allows us to mark messages as spam and it dutifully moves them to a spam folder. To be honest I’m not sure exactly what communication then takes place with the IronPorts if you do that, but I do know that it loads a DLL, making it unusable on our OSX boxes.

The second anti-spam system is the SenderBase Reputation Score (SBRS), which we are not yet using. This looks up the address of the MTA that connects to the IronPorts in the SenderBase database and assigns it a score of -10 (definitley spam) to +10. You can then decide how different ranges of scores are handled. SenderBase assigns scores based on a number of different sources, including SpamCop, which ironPort owns along with SenderBase. This probably explains why the IronPort does not support RBL or DNSBL services directly, since they all go into SBRS.

Once of the nice features of the IronPort is that you can choose to accept messages from a particular source but throttle the number of messages it can send.

You can configure the IronPort to share its logs with SenderBase to help increase the effectiveness of SenderBase. However we have at least one MTA that receives mail before the IronPorts, processes some that matches a particular format and forwards the rest to the IronPorts. Since this MTA receives a lot of spam it does mean that the IronPort sees it as a source of spam. So if you share your data with SenderBase and you have this particular setup then you can actually end up giving your own MTAs a bad reputation. For that reason we have had to disable sharing with SenderBase. Unfortunately you cannot turn off this sharing on a per MTA or per group basis.

The final integrated product is Sophos anti-virus, which comes with all the usual features though it is much easier to configure through the IronPort interface than normally.

The most unusual thing about the IronPort is that it runs their own operating system, based on FreeBSD, called AsyncOS. This claims to allow for extremely high volume processing but we have not yet tested it to destruction (though with our excellent Spirent Avalanche we could always try). One side effect of the use of AsyncOS is that it never writes the email to disk, so if you have a power failure after it has received a message but before it has forwarded it, then that message is lost.

The IronPort has quite a nice web interface through which you can configure the box, view reams of statistics and create adhoc and scheduled reports. The actual configuration concepts are fairly obtuse and unfriendly. It takes a few reads of the manual to understand them and configure it correctly. You can do all sorts of custom filtering, for example we do not allow anyone to connect to us specifying a hostname in our domain in their HELO command. However finding where to set this kind of thing is not always obvious. In this example it appears at a point that I think is much too late in the mail handling process, since of course the HELO command comes first. Despite the awkwardness we haven’t yet found anything we can’t get it to do.

We’ve used IronPort support and they were quick and helpful. IronPort do password protect their online manuals and knowledgebase, but with a username/password combination that is obviously shared by all users, so it just acts as an irritation.

The IronPorts are expensive and I can see why you might not want to fork out this much. Bear in mind then that you could always build something similar yourself. Brightmail is available to purchase directly from Symantec, and of course Sophos is widely available. SenderBase is actually free to use, even though it is owned by IronPort. So you could always install your own server with a decent mail server like Postfix and add on these services. The one thing you might miss is the IronPort reports but I guess Brightmail probably does a lot of that.

Recent Posts

Highest Rated

Categories

Archives

Meta: