08 September 2007

Broken Window Number 1: Replaced.

I had a strange bug in the client part, which only occured when running the code after it was compiled to Javascript by GWT (GWT Web mode) and not when running in hosted mode (GWT Hosted mode). It was a pain to pinpoint the location of the error - I had to place popup messages stepped through the application to determine its location as all I got from the browser was "uncaught exception" and a GUI which failed to display. When I ran it in Hosted with the Eclipse debugger for support, well it was pointless as it worked perfectly.

I discovered the problem was with the code which deals the cards to the two players. This makes use of the .clone() method of the TrumpStack object, basically just an Arraylist which represents the stack of Trump Cards. Another method shuffles the cards, the deal method then gives the entire card deck to to player, clones a copy to the opponent, deletes the top half of the cards from the players deck and the bottom half from the opponent's deck.


private void dealPack() {
// Give opponent half cards.
_session.setOpponentStack((TrumpStack) _session.getPlayerStack().clone());
_session.getOpponentStack().clearFirstHalf();
_session.getPlayerStack().clearLastHalf();
}


Turns out the behaviour of .clone() differs between web-mode and hosted. In the hosted implementation .clone() makes a copy of the TrumpStack object (which is basically an Arraylist) and all the elements too. In the web mode version the elements are not cloned but just the object (?!). This is doubly odd as the Sun API (Sun API Documentation) implies that the web behaviour is correct, although when running in Java that is not what happened.

What happens is, when the code accesses the first card in the opponent's stack of cards it gets a null value, which causes an error in Javascript. That at least, in the absence of better Javascript debugging tools, is what I think is happening.

In any case I have implemented my own method called .copy() which does copy all the elements, which I have then been able to give a return type of TrumpStack, getting rid of the need to cast in the dealing code above. I have also place a check for nullity in method which accesses the opponents first card. This might happen for example if the player only has one friend.

Labels: , ,