Sunday, February 5, 2012

You're Not the First to Have This Problem

This is going to sound like the "compiler bug" problem, but this time it was something very similar. Yes, there are probably some bugs in the JDK. The likelihood of there being a bug in any software increases along with the size of the codebase. (Unsubstantiated claim, but I provide no footnotes with this blog.)

Anyway, when you hit a problem keep in mind that you're never the only person to have encountered this problem. Somebody else has seen it and probably been in a more desperate situation to need a solution.

Every once in a while I'd see some odd stuff going on where a bunch of threads seemed to get stuck. Those threads interacted via a CORBA interface, so I just chalked it up to some CORBA-wackiness and thought I'd try to code a way to kill off those threads when they got stuck waiting for CORBA to finish.

Sidenote:  CORBA came from the OMG, which has the most ironically appropriate acronym ever invented, because "it's like, OMG, could there be anything better than a consortium named OMG!?"   By the way, do not click over to the talk page on Wikipedia entry for OMG if you're in a quiet professional environment -- I started laughing so much my wife thought there was something wrong with me.

So anyway, I got a recent thread dump (not a stacktrace, since those threads didn't throw any exceptions, they were just waiting) and decided to look around a bit for the answer. Here's a sample of one of the stuck CORBA threads:


"pool-538-thread-1" - Thread t@67441
   java.lang.Thread.State: WAITING
        at java.lang.Object.wait(Native Method)
        - waiting on <5dfd006a> (a java.lang.Object)
        at java.lang.Object.wait(Object.java:485)
        at com.sun.corba.se.impl.transport.CorbaResponseWaitingRoomImpl.waitForResponse(CorbaResponseWaitingRoomImpl.java:140)
        at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.waitForResponse(SocketOrChannelConnectionImpl.java:1084)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.waitForResponse(CorbaMessageMediatorImpl.java:253)
        at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete1(CorbaClientRequestDispatcherImpl.java:362)
        at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete(CorbaClientRequestDispatcherImpl.java:336)
        at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:129)
        at com.sun.corba.se.impl.corba.RequestImpl.doInvocation(RequestImpl.java:309)
        at com.sun.corba.se.impl.corba.RequestImpl.invoke(RequestImpl.java:230)
        - locked <6dae8354> (a com.sun.corba.se.impl.corba.RequestImpl)
        [etc., etc...]


I stumbled around the Interwebs for a bit and happened upon the inevitable similar stack traces and mentions in a forum or two or three, but none of them had the answer. Then I expanded my search a bit and  found an existing item (7016182) in the Java bug database... submitted about a year ago and a status of "Cause Known" but now what?  So I searched on the related bug ID numbers and found yet more info in number 7046238. Yay!  Finally an answer!  It says it's been fixed in JDK release 6u27 which I'm pretty sure is 1 update newer than what we were running.

That's good news, but it still needs to get tested. In the meantime, I compared the source of the affected JDK class CorbaClientRequestDispatcherImpl with the the fixed version. Yep, just as the bugfix note said, the fix is a change to how the synchronization is handled and it makes me glad I didn't have to try to figure out how to fix it. In a way it's comforting to know that even the experts sometimes make mistakes.

Anyway, that was my adventure this weekend. What did you do?

Thursday, February 2, 2012

Modeling Intangible Many-to-Many Relationships

Modeling intangible things in a data model takes practice.  Here's an example I've used and choices made along the way.

Visible and Real

Set aside the database "join table" for a moment and consider how you represent your primary entities in code.  Sometimes it's easy to see how the concepts should map to database tables and Java classes -- especially when the concepts are relatively visible in the real world.

Let's take, for example, my favorite model:  Creature - Skill - Achievement.
Creature is obviously a visible "thing" that exists in the real world.  Skill and Achievement aren't quite as visible except in a temporal sense, but at least while you're watching a Creature swim (or whatever other activity), you can see that it's happening with some level of skill.  An achievement like "first place" or "swam 10 laps" may be represented by an award of some kind but there the visible thing is just a reminder of an achievement, it's not actually the achievement itself, but somebody saw it happen so at least for a moment it was real.  So really this one isn't so hard to wrap our minds around.  We can have Java classes with a 1-to-1 correlation with the database tables and it all pretty much makes sense.

Invisible Things

But when entities represent something intangible the mapping isn't as clear.  A few years back this situation cropped up in a development effort where I was a (pseudo) dev lead.  Our application was going to deal with People and Decisions.  In this instance a "Decision" could be something like a "Decision to Exercise Regularly."  Each Person could have many Decisions.  Each Decision could be made by several People.  Thus, a many-to-many relationship.  So how do we model this?

or translated into something nearly equivalent...
The database folks already had the tables set up as  Person, Decision, and PersonDecision which followed their standard naming conventions.  And, at least with a traditional database, this is how a many-to-many relationship is created.

Option 1.
Should we stick with a 1-to-1 mapping from database table to Java class?  In that case a Person object would have a collection of PersonDecision objects and some field there in the PersonDecision class would show what kind of Decision was made by the Person.  This option has the benefits of being a simpler implementation for mapping.

Option 2.
However, it could be argued that each Person object should directly have a collection of Decision objects, with any necessary metadata from the database's PersonDecision table as fields in the Decision class.  This option has more object-oriented beauty about it and avoids the awkward PersonDecision name.


Consider the Usages (and the kittens)

We could have talked about it for days but there was a lot of work ahead of us so I went with my gut and chose for us to go with the first option (though there was some further discussion expressing respectful disagreement).  The major factor for me is that there was additional data attached to both Decision and PersonDecision (such as EventDate).  Also, there were some usages within the application that involved only Decision and not Person or PersonDecision.  So even if we had merged the data from the two tables into one class, it would still have required a Template Decision  class representing an archetype of a Decision separate from a Person.  Thus we would have still needed an additional class, just perhaps with a different name, putting us back into situation we started with plus some additional complexity.

Who really knows whether or not my choice was the correct one.  It's the one we went with on that project and it didn't feel like we had to jump through a lot of hoops to make things work.  Revisiting it, maybe it would be nice to implement it both ways to compare the merits of each option more closely.  But that's a topic for a different post.