Caching in Tomcat - SOLVED!

June 19th, 2007

It took forever, but I've finally how to stop Tomcat adding a Pragma: no-cache header to any resources in a secure context. You need to set disableProxyCaching to false, so if you're using basic authentication you need a valve like:

<Valve className="org.apache.catalina.authenticator.BasicAuthenticator"  disableProxyCaching="false" />

That needs to go within the <context> definition for your web-app. So, within the META-INF (some sources say within WEB-INF?) create a context.xml file like:

<Context><Valve className="org.apache.catalina.authenticator.BasicAuthenticator"  disableProxyCaching="false" /></Context>

I found deploying as a WAR didn't work (it seemed to ignore the context.xml), but deploying the exploded files did work and that's fine by me.

Combine that with the awesome cache control filter that Danny posted in the comments and you have a very nice, easily configurable caching mechanism that doesn't cause browsers to download the CSS and JavaScript resources for every single page.


Dear lazyweb,

Does anyone have best practices for implementing correct, useful caching for a webapp running in Tomcat? I'm using container managed security and it's happily adding Pragma: No-cache to everything, including the static CSS file which is pretty brain dead. It looks like I can add a custom filter to get rid of that header and then manage caching myself, but it seems like something that everyone should have solved before so I thought I'd ask….

Thanks,

Lazy me.

Wowsers! Sun’s Updating The Swing Text APIs

June 19th, 2007

Apparently Sun has finally decided to give some love to the Swing text APIs with the addition of a removeElement method. What the linked article fails to mention is that in the particular example given, you can remove the list item with a simple document.remove(e.getStartOffset(), e.getEndOffset() - e.getStartOffset());

When you get into trouble with the swing text apis is when there are two elements that start and end at the same point - ie: a list as the only child of a table cell:

<table>
  <tr>
    <td>
      <ul>
        <li>Remove me!</li>
      </ul>
    </td>
  </tr>
</table>

If you try the document.remove trick, the entire table will be deleted because the start and end offsets for the list item is the same as for the table (they contain the same text content). Unfortunately, the new removeElement method won't help with this because if you remove the last child element it also removes the parent element so document.removeElement(li) has the exact same effect as document.removeElement(table). The work around for that is of course to insert another element into the table cell first - most likely an empty p or p-implied element which you can do with insertBefore or insertAfter, but not if you want the table cell to be empty because you can't insert the required p-implied and line ending with insertBefore or insertAfter. Instead, you'd have to insert an empty p tag and then use document.setParagraphAttributes to convert it to a p-implied after the fact. That or insert some text and then delete it again (but keep the trailing newline that will be inserted automatically). Both those cases will make a mess of your undo buffer because they count as two changes instead of one.

Improve Your Code By Writing About It

June 18th, 2007

I've spent a fair bit of time writing articles for LiveWorks! lately - posting weekly isn't as easy as it seems, particularly when you have three weeks leave coming up. Most of the articles include some kind of code, be it JavaScript or Java and an explanation of what the code does, why it does it and how you might use those techniques in other ways. As I go through writing the article trying to explain my code it really highlights how nonsensical my original design decisions are. Even when I've gone back over code and carefully refactored it to be clear, when I come to write the article I almost always rearrange things again.

Now, explaining things is well known to be a good way to get a better understanding of them yourself which is essentially what's happening here, however I don't see the same kinds of effects when I explain code verbally. I suspect this is mostly because I don't want to go changing the code while I'm part way through the explanation (which would make it hard to follow) so while I might see the code smells I don't tend to actually fix them. The other aspect is that when you're writing an article you have a lot more time to think about it than when you're explaining verbally. There's not someone sitting beside you that feels uncomfortable if you just go quiet and think for a few minutes (or jump in with questions etc).

That's not to say that verbal explanations aren't useful - they are much quicker to do and make asking questions much easier for example. The difference is that verbal explanations provide benefits in terms of greater understanding for the listener and the explainer, whereas written explanations provide slightly less understanding - particularly for the listener who doesn't get to ask questions - and takes longer, but provides much better opportunities to actually improve the code.

I must try to remember this the next time I need to refactor code and at least think through how I'd write an article about it, if not actually write the article.

My Shiny New *Ferrous* Whiteboard

June 15th, 2007

For quite a while we've lamented the lack of whiteboards in our office and talked about getting some in. A week or two ago Brett actually arranged it and so I've wound up with a lovely big whiteboard above my desk that I happily draw all over. I've always been a big fan of whiteboards for problem solving or brain storming sessions, even if I'm working alone. Something about the big open space and ease of erasure makes it so much better than paper.

The other cool feature of my whiteboard is that it's ferrous - or at least it would be cool if I had any actual magnets to stick on to it. After a tour around the every likely source of magnets I could find at the local shopping mall without finding anything suitable1, I turned to the internet. Turns out I found a company that not only is seriously into internet marketing, they also have some seriously cool looking magnets.

So, at this point I need to explain that I am absolutely selling my soul - I mentioned these guys were into internet marketing - they actually give free magnets to anyone with a page rank of at least 1 that links to their site. Frankly they are a seriously cool looking type of refrigerator magnet and I want some. So hopefully, that link there is my ticket to a whiteboard with magnetic push pins that are strong enough to hold a hammer (I'm hoping they're easy to lever off the whiteboard again…). Seriously, go click that link just to see the picture of the hammer.

Now the downside of these magnets in a software development environment is that they are really strong and so quite likely to wipe hard drives, damage monitors etc. I'm going to have to sort out some way to protect my laptop which sits right under the whiteboard, but the ability to stick story cards on the board and be able to write notes around them, circle them in various colors etc is just too desirable to miss so I'll find a way.

I am also a little disturbed by my inclination to want to start a magnet collection. The other downside is that I've just set the price of my soul at a half dozen cool looking magnets. Combine that with few people taking the initiative to send me cool looking magnets2 and the space on my whiteboard and my blog may suddenly be filled up…

1 - I did find one packet of alphabet magnets but as cool as they are, they didn't look like they'd be useful for sticking things to the whiteboard

2 - Just send them to our office, preferably the Australian one but they'll get to me eventually either way.

Clever Spam Reduction Technique

June 14th, 2007

I discovered one of our client's company blogs1 tonight because they mentioned they'd just upgraded to EditLive! 6. Reading through the backlog I discovered they've found a clever way to reduce the impact of form spam that I hadn't come across before2 - only accept the submission if it uses multipart/form-encoding not just a plain post. Like most techniques it won't work if everyone does it but it's another interesting way to differentiate.

I do have to wonder why spam bots aren't all just using an embedded browser these days though3 - there seems to be a huge number of ways that they get caught out needlessly.

Anyway, I noticed in their support history there's a feature request I can solve for them easily via our plugin architecture. If someone could throw a squishy toy at me in the morning to add it to the list of LiveWorks! article ideas that' be great4.

1 - note the first cool use of blogs - learning about your customers

2 - note the second cool use of blogs - learning interesting stuff that may or may not be useful in the future

3 - watch the comments for the third cool use of blogs - I'm sure someone will have additional insight on this

4 - note the fourth and most cool use of blogs - using the inherent delay as a reminder mechanism5

5 - also, footnotes are cool and I just haven't used them enough lately