Pass-By-Reference Problem When Using Websphere Application Server

This has been kicking around, nearly finished, for months. It’s not going to get any better, or shorter, so it’s long past time I put it out there.

It’s also just long; and technical. So feel free to ignore. I won’t be offended.

I rarely write about programming or other technical issues here, but I probably should do so more often. Certainly in a case like this.

I often think about the many, many problems that I’ve had help with from strangers on the internet; people who have taken the time to write blog posts, answers to questions on forums, or technology tutorials. My job would barely be possible at times without the web. Of course, we didn’t have it back when I started in 1987; but we didn’t do such complex things, with so many different languages and technologies.

Anyway, all these kind strangers have helped me, and I rarely find myself in a position to give anything back to the community. So since I recently hit a problem that no-one else seems to have had, it’s really my duty to describe it, and my solution, in the hope that it might be of use to someone down the line.

If you’re looking for the solution to the problem with pass-by reference on WAS, and don’t want to read the story of how I got there, you can jump straight to The New Bug

Background

We develop our main app using a fairly standard n-tier architecture using JEE: web front end using JSPs and Struts; EJBs; a multiplicity of database platforms accessed using Spring. All fairly standard stuff, whose purpose is to move financial messages around.

A lot of this was originally developed when I wasn’t around (I was seconded to another department) and by contractors and others who are no longer with us. So I take no responsibility for the stupidities that exist in codebase. Or rather, I accept no blame. I do, in fact, have responsibility for it; for keeping it going and developing it onwards now.1

One of the bad choices that was made by the original developers of this version of the product, was that they should cache the results of database queries. The users can define various criteria by which they want to select a set of messages to view; those get translated into SQL, which our Java code executes using JDBC. Again, all standard stuff. JDBC was designed for exactly that kind of thing. Databases exist solely to do that kind of thing.

So the wise and sensible developers decided that performance would be a problem if a query returned many rows from the database. They decided that transferring the rows to the browser and allowing the user to scroll through them would be impossible. So they designed a caching mechanism.

Thing is, JDBC has that kind of caching built right in. And furthermore, they (our developers) included a limit: a maximum number of rows to return, which could be set to 50, 100, 500, or 1000. Pretty reasonable, since any query that returned over 200 or so rows is likely to be less than useful, anyway.

But they still built that caching mechanism.

The Mechanism

That’s all right, though, I hear you say. Cache the rows server-side in memory, return a subset to the user as they page through them. It sounds fine.

True enough. Except they didn’t cache them in memory. Oh no. That would have been too sensible. And might have caused performance problems (I’m sure they thought, if they even considered they matter). No, they cached them elsewhere. Where? In the database.

Yes, they introduced another table; a shadow table; an almost-identical duplicate of the Messages table, called MessageQueryResults. Executing a query then consisted of selecting the required rows and writing them into this table, keyed by the HTTP session ID; and then re-querying this results table to get a page worth of results.

So, to recap, then: to improve performance (without first determining that there was actually a problem), they replaced a simple database read with a read, a set of writes, and another set of reads.

That was bound to perform better, right?

The Failure

It wasn’t performance that brought this flimsy edifice crashing down, though.2 No, it actually ran quite successfully for several years. Three things brought about its end: Microsoft, multiplicity, and me. 3

Microsoft’s part was through their database platform, SQL Server. Between one version and another they changed something about their storage mechanism, so that you could no longer rely on rows on a table being in the sequence in which they were written to the table. The thing is, you’re not supposed to be able to rely on that, according to DB theory. That was another flaw in the “design” above; it relied on the shadow table’s rows being returned in the same sequence they were written in. On Oracle and DB2 that worked; and it did on SQL Server too, until (if memory serves) the 2005 version. This meant that clients on that platform who had large queries couldn’t rely on them being displayed in the right order.

Oh dear.

Hacks were applied to sort this out. Pun intended: sorting is pretty much what they did. Not a fix, but a workaround at best.

The multiplicity part was that the same mechanism was used to query another table; and then a third. And there was a fourth on the horizon. Each new table meant a new shadow table which had to be maintained in parallel — and whose creation and upgrade scripts had to be maintained across three database platforms. A maintenance nightmare.

Then there was me. I had known about the problem for some time, of course — I had done an estimate for fixing it — but there was never time to fix it. It was a big task, quite intrusive, and showing no easily-provable customer benefit. Yes, I know ease of maintenance, by making life easier for developers, is an implicit customer benefit; but try selling that to management, when there are customers crying out for new features.

But in the project that was to introduce the fourth table (or seventh and eighth, you might say) I was in a position to say, “we fix this first, or it all goes to hell”.

The user story was written. I got my estimate out of hibernation (and increased it, of course). And then I did the fix. It was a great joy. That in-memory caching mechanism I mentioned above? I did that. If I’d been designing it from scratch I would almost certainly have relied on JDBC’s internal caching, at least until it proved problematic. But under the circumstances, when the code relied on there being a cache, it was going to be much less disruptive to retain one. I just replaced the stupid one with a more sensible one.

Inevitably, though, I introduced a new bug.

The New Bug

This is where I stop telling a story and start explaining the problem and solution.

Introducing the new message caching mechanism, which replaced the MessageQueryResults table, inadvertently caused a problem when we set a WAS server to pass-by-reference mode.

This mode is recommended when the different tiers of the application (web, EJB) are running in the same JVM. This is normally the case in our test environments, and frequently the case in client systems. Enabling this mode removes the need for objects to be copied as they are passed through the tiers, and can improve performance dramatically in such environments.

What Went Wrong

Changing the caching mechanism caused no problem as long as pass-by-reference was off. As soon as it was turned on, we noticed that taking certain actions, such as deleting a message, failed.

The failure was at a point in the code where the a value such as an amount was being retrieved from the Map that formed the new cache. The failure was that the retrieved Object was being cast to a Number, but what was in the Map entry was actually a String.

This Map comes, by a fairly complex set of steps, from the new cache, and before that from the database itself, of course.

Now, since the Amount column on the DB is numeric, and the Map in question is originally populated via Spring from the DB, obviously the value was a numeric one originally. This suggested that the value must have been changed, and that gave us the first clue to tracking down the cause of the problem, and coming up with a solution.

The Cause

It seemed likely — and running debug, it was shown to be so — that the numeric value that was retrieved from the database and stored in the Map was being replaced by the edited value which is built for displaying. In other words, the object now contained a String holding digits, a decimal point. and probably commas.

Why it Changed When We Switched on Pass-By-Reference

When the data was being passed by value, a new Map, complete with its contents, was being passed from the EJB layer to the webapp. The webapp then updated values in that Map, editing them for display purposes. But it was only changing its own copy; it had no effect on the version stored back in the EJB layer. So when the same Map was retrieved again, so that the action could be performed, a new copy was received by the webapp. No problem.

But when pass-by-reference is on, no copy is made. The webapp receives a reference to the actual Map that is stored in the cache back in the EJB layer. So when it updates an entry in that Map, it updates the very object that is stored in the cache (note that the put method of the Map interface will update the stored value if it receives a key that it already holds).

And then when the Map and its entry are retrieved again for the action to be performed, it is the updated (and now wrong) version that is retrieved.

Why it Changed When We Changed the Caching Mechanism

And yet both possible passing settings were available before we changed the caching mechanism. Why did we not get this problem when using pass-by-reference with the old caching mechanism?

The answer to that is that the old mechanism cached the query results in the database itself, in the MessageQueryResults table. Each time a set of results was requested by the webapp, the EJB layer went back to this temporary table and populated the Map that it returned to the webapp. So the amount value would always have been set up freshly from the numeric Amount column, which ensured that it was an object of type Number.

The Fix

I tried making copies of the Maps and Lists used, at various points in the process, including using ImmutableLists and ImmutableMaps from Google’s Guava library, in an attempt to prevent the value object of interest from being updated. However, it wasn’t possible to make them immutable deeply enough (and would probably have caused other problems if it had been). That was largely because the principal Map is created and populated by Spring, so we don’t have much control over it.

One solution — and probably the proper one — would have been to copy the entries from the Map at the point they are read and processed in the webapp. This would have meant that the edited, String, version of amount would be a different, new object, and would not have been updated in the Map that came from the cache.

However, the vast complexity of the class where this would have had to happen made this seem like a very difficult and dangerous approach, especially at this late point in the project.

An alternative solution was suggested by one of my colleagues. It was to accept the fact that the amount value might be a String containing a numeric value with commas and decimal point, and to parse the numeric value out of it.

This allowed us to cater for both numeric and string values, and it worked with either form of passing semantics. But it felt like a hack, and I was sure it would come back to bite us.

Fixing the Fix, a Little Later

It did. The trigger this time was paging through the list of results; when you returned to a page you had already seen, you ended up with an object of the wrong kind coming out of the Map. If memory serves it was a String where it should have been a Date.

It was clearly another result of the data being edited for display and updated in-place in the Map. There are too many possible places in in the relevant method to rely on finding them all, so I returned to the “probably the proper” solution mentioned above. I changed the relevant method such that it now returns a copy of the List containing the required subset of the query results. This is less straightforward than might be hoped, because copying a List, including by the clone method of the implementing class, for example, tends to do a “shallow copy”, which means that you get a new List instance, but containing references to the same objects.

I wrote a method called copyList, which iterates over a List and makes “deep” copies of a few expected types of object. We may have to extend this method to handle other types, but I don’t expect that at the moment.

Also Worth Noting

There is a warning about this on IBM’s Best Practice: Using pass by reference for EJBs and servlets if in same JVM page, but it’s one of those typical contrived kind of examples that probably wouldn’t really alert you to the possibility of something like my experience.


Notes

To set the pass-by-reference mode on or off, take the following steps in the WAS administrative console (this is WAS 6, it’s probably different at other releases).

Go to Servers -> Application servers -> <server -name>

Expand Container Services; click on ORB Service; check/uncheck "Pass by reference"


  1. Not just me, I should note. []
  2. Or more folding down, slowly, over years. []
  3. I love a bit of alliteration, don’t you? []

Cluttered by Google, Lost by Bing

I was reading The Clutter Didn’t Kill the Love by Brent Simmons, about how he was trying Microsoft’s Bing search engine, instead of Google. His reason was the current worry that Google is becoming less than trustworthy.

Google losing trust would be a shame. But at least a Google search for “martin mccallion” (without the quotes) has this blog as the number one hit. Try that on Bing at the moment and you get a whole pile of other Martin McCallions.1 The worst part to me is that the first six are Facebook or LinkedIn profiles (the seventh is one of those annoying directory sites, then you get me).

I wouldn’t mind other people with the same name appearing above me, if it was their proper sites; but to me social-network profiles feel like distinctly second-class web entities.

Or is that snobbish?


  1. As an experiment, and to ensure a like-for-like comparison, I signed out of Google, and went to the .com version (I normally use .co.uk by default). I was still at the top. []

The Felice Brothers

As if there weren’t enough reasons to love Outnumbered already, we recently saw an old Christmas special. It ended with the family watching the telly and singing along to a song. I didn’t know it, but liked the sound of it.

The internet knows all, and a bit of googling told me it was ‘Frankie’s Gun!’ by The Felice Brothers.

Emusic has the relevant album, and it’s great. Highly recommended.

Also their site tells me they’re playing London on the 20th of March. Hmmm…

The Words that Maketh Novels

It seems like almost no time at all since I last wrote about not completing NaNoWriMo. But here we are again. A year passes like nothing.

I wasn’t strictly following the rules (but they’re only really guidelines, and optional at that) in that I wasn’t starting a new novel this time. I was carrying on the same one that I started last year, and I hadn’t written many more in the interim. I managed just under 15,000 words this year, which is slightly less than last time (and less than a tenth of my erstwhile OU Creative Writing classmate Karl’s crazy figure)

It has, however, given me a new kickstart, and I intend to carry the momentum onwards, but at a more manageable rate. My novel (working title Accidental Upgrade) currently stands at around 36,000 words. I’ve set myself a target of 80,000 by the end of February. That is more like the length of a modern novel, and achievable at a rate of around 475 words a day, according to Scrivener.

That’s much more feasible for me than Nano’s 1667. Though I’m just realising that I said essentially the same thing last year, and it obviously didn’t work. Still, I feel more confident this time. I wrote around 600 words today, and I’ve got Scrivener to help me keep on track.

Smashing Things Up for 35 Years

My friend (Wee) John(ny) called a couple of days ago and said, “Do you fancy seeing The Damned at the Roundhouse?” I’d never been to the Roundhouse, though it was one of those legendary London venues from my teenage years, like the Rainbow and the Hammersmith Palais. And I hadn’t seen The Damned in (I thought)1 about 26 years. Not since a seated gig in the Edinburgh Playhouse the night before I had a High-Energy Physics progress test the following morning.2

I said “Yes”. I mean, why the hell not? I only really know Machine-Gun Etiquette and a few singles, but what the hell. They’re bound to do those, right? It’s a 35th-anniversary thing.

The Roundhouse is an amazing place. As a former railway shed, it’s just a stunning space. But it’s not the seedy old-school venue I half expected, because it’s been closed down and refurbished and reopened since the seventies. So it’s really nice: more like The Barbican, say, than The Forum.

Viv Albertine was supporting. I expected her to have a band, but she just stood up there on her own, with a Telecaster as old as punk, and sang us songs of non-love and stuff. She was great.

The Damned were… pretty much as I expected, actually. They came on, and the Captain said, “We’re going to do two ‘classic’ albums.” (He did the air-quotes.) I’m not sure about this recentish trend of doing a whole album live, but expect it could be good. Mostly, though, I’m amused that for classic punk albums, one would be too short.

So they kicked off into ‘Neat Neat Neat’, and I realised that we were much too close to the front: actually in the moshpit. As I’ve said, I’m really past that — much though I might enjoy dancing in the abstract, or in private.

Anyway, it was all very wild and excellent, and there were many people with t-shirts of bands I’ve seen or haven’t seen but wish I had or don’t mind that I haven’t but recognise anyway. In short, I was with, as Neil Gaiman describes it, my tribe.

It was all monstrously fine. Two albums with a break, then a few encores. Which included, as expected, several non-those-album tracks. ‘Love Song’, of course, they could hardly have avoided playing. A couple of others, and then came ‘Eloise’, which, punked-up though it was, we could frankly have done without,

Then they played ‘Anti-pope’ and were gone. I realise that the Roundhouse must have a strict 11 o’clock policy, but surely they were coming back…? No. DJ music and house lights… and no ‘Smash it Up’. I must admit, if you had asked me before I went out tonight whether there was any chance that they wouldn’t play ‘Smash it Up’, I would have laughed at you.

Very strange. And then there was a crazy queue to get out of the venue, because so many people had taken up the option to get an instant double CD of tonight’s gig. They obviously burn them straight from the sound desk while the gig is on. But it meant that you could hardly get out of the venue. There has to be a better way than that.

Anyway, my ears are sizzling, and I still owe NaNoWriMo a load of words, so I’ll call it a night here.


  1. Johnny reminded me that we saw them at a festival in Milton Keynes Bowl in about 88 or 89. []
  2. Though it’s entirely possible that I’m conflating that with my friend Andrew’s 21st birthday, which I also remember as being the night before a HEP exam. []

88 Lines About The End Of Reasons To Leave The Elements

Back when John Peel was still with us he played a song called ‘88 Lines About 44 Women’. I only heard it maybe twice, and never caught the name of the band. Later, when it became easy to find things out, I discovered they were called The Nails. I’ve recently been rediscovering that very fine song, which I like as much as ever; and I’m pleased to find that there are couple of different versions of it.

(According to the Wikipedia article on the band, Jello Biafra was their roadie, which was a strange and surprising discovery.)

It reminded me that I have a fondness for list songs, which as you can see from the link, is a sufficiently real genre, or class, that it has its own entry.

So I made a Spotify playlist of some I like. Click that link if you have Spotify, or this one if you don’t. Unfortunately it won’t show the contents of the list — there doesn’t seem to be an easy way to do that. It will just prompt you to sign up.

There’s a song on there by The Beautiful South which, if I remember correctly, was intended to mock the use of women’s names in songs. I wonder what they’d think of ‘88 Lines About 44 Women’.

Aliens Among Us

I never bothered to watch Alien Resurrection because I didn’t like Alien3 (or Cubed, as I always see it). So now, browsing the new, freshly-in-beta SF Encyclopaedia I find it was written by Joss Whedon (who doesn’t yet have an entry in said volume, but no doubt will have eventually).

Why did nobody tell me this?

It seems a particularly timely piece of information as we’ve been introducing the kids to Buffy recently (in part to get us all over the lack of Doctor Who), and also to Firefly. We are deep in the Whedonverse.

Hardcore Knows the Score

For the last two months or so, it seems, I’ve been listening almost exclusively to a single album.1 That album is David Comes to Life by a Toronto hardcore band called Fucked Up.

That’s hardcore in the punk sense, not rap, or anything else. All genres have a “hardcore” subgenre, it seems. I’m sure that somewhere there’s hardcore pop.

Anyway, this album causes me to put together three words that I never thought I’d see in the same sentence, never mind describing the same thing: punk rock opera.

I know, I know, rock operas are the bloated detritus of prog rock, and part of what we fought the punk wars against. Though truth be told, I’ve always been quite fond of Tommy). But in a sense it was always something that was going to happen eventually. When a genre or a medium has been around for a while, people will try to take it further than it has gone before, and that’s no bad thing.

And when you get right down to it, it’s all about storytelling, and who can complain about that?

So I was pointed in the direction of this album by a post on Mike Sizemore’s blog. Sizemore is a scriptwriter; I probably started reading his blog when someone like Warren Ellis pointed me at a teaser or “sizzle” video he and some other people made for a prospective science fiction series.

Anyway, he posted a link to the video for the second track off the album, ‘Queen of Hearts’, and spoke very highly of it, as you’ll have seen if you followed the link. If you haven’t, you should. Go on, I’ll wait. I watched it a couple of times, and though, “That’s OK, interesting premise, I wish I could make out the words.”

And then I forget about it for a while.

But one day something made me go back. I listened again. I downloaded the album. I fell in… not love, exactly, but fascination.

North American hardcore bands have a certain vocal style, which is certainly not to everyone’s taste. In that way, I realised, it’s not unlike actual opera. Sure, they vocal stylings are about as far apart as possible; but they are both very stylised. And my biggest two problems with opera are that it’s hard to make the words out (even when they’re singing in english), and that I don’t really like the vocal stylings.

Not to everyone’s taste, as I said.

Luckily, operas tend to have surtitles; and albums have lyric sheets. The lyrics for David Comes to Life are available on the web, as you might expect.

Anyway, I’m writing about this now because I haven’t got round to doing so before, but especially because I’ve just got back from seeing Fucked Up live. They were playing at a Shoreditch venue called XOYO in a “co-headliner” with a band called OFF!).

I tweeted a lot about it, and among other things, I expressed a degree of concern as to what it would be like going to a hardcore gig:

Going to see Fucked Up and OFF! tonight. Not sure what to expect. Haven’t been to a hardcore-type gig since… Napalm Death in 88 or so?Thu Aug 25 07:59:44 via Echofon

Hmm. Not seen a hardcore gig since Napalm Death? That may well be true, but they’re British (and technically grindcore, according to Wikipedia). I began to wonder whether I’d ever seen a US (or Canadian) hardcore band live. The only one I could think of were Hüsker Dü, whom I saw in Edinburgh in — oh, 84 or 85.

I feel sure there must have been others, and yet the only such band that I was really, really a fan of was the Dead Kennedys, and if they ever played the UK it happened either without me knowing about it, or they only played far away from where I was, or both.

I needn’t have worried, though. The venue was just the right size, and comfortably packed. The crowd were gentle and lovely. The moshpit was pretty wild, but I turned 47 yesterday, which is officially way past too old for the moshpit, and I was well able to stay clear of it.

And it was a totally brilliant night. The first band, Cerebral Ballzy, were on when I arrived, so I heard three or four of their songs. They sounded pretty good, and more to the point, the sound in the room was excellent. Clear, and powerful, without being so loud as to be overwhelming.

OFF! were classic hardcore, in that if you didn’t like a song there’d be another along in way less than three minutes. I thoroughly enjoyed them.

And Fucked Up just ruled. I was thinking before they came on that I would leave happy as long as they played ‘Queen of Hearts’ And they duly opened with it! They then proceeded to play edited highlights from David Comes to Life, interspersed with a few other tracks. There was stage-diving, crowd-surfing, the singer diving topless into the audience and walking almost to the back of the venue while still singing (and using a wired mike, with a very long cable).

Anyway, if you’ve read to the end of this rambling thing, you should go and listen to some things. Here’s the ‘Queen of Hearts’ video, and it’s the first time I’ve ever embedded a video. Let’s hope it works. Note that this version has the kids in the video singing on it, which is not how it is on the album, but is very cool nonetheless.

And the second video from the album, ‘The Other Shoe’, which they also did tonight.


  1. Though in old-school terms it would almost certainly be a double album. []