Automation of Burn-up and Burn-down charts using GScript and Entrance

I have always found that the burn-up and burn-down charts are very informative and fit to the iterative story-based development very well. Every project that I work on, I will try to figure out different ways to generate burn-up and burn-down charts.

Two months ago, I took the job on putting Platform on Sprints. After some consideration, I have decided to follow the setup that I have for the AF team, creating the stories in the form of JIRA issues. However, the chart generation that I had for AF team was still semi-manual, which means that it takes a couple of minutes to download, and a couple of minutes to update the stats every morning. The worst part is that when I get busy or sick, I will forget.

So my first action item was to figure out how to generate the same kind of charts with the push of a button. The idea seems to be easy enough:

  1. Figure out the search criteria to retrieve all the JIRA issues of the backlog
  2. Count the issues that are in different states
  3. Update the data with the counts, and check it into Perforce.
  4. Refresh the chart with the updated data

Number one and two were actually not that hard, because Guidewire GScript has a nice WebServices support. With a few tries, I was able to count the beans.

Here is an example of the data generated. I think you get the idea just looking at it.

Date,Day,Closed,Deferral Requested,In QA,Open Stories,Open New Features,Open Bugs
10/09/2009,41,55,0,1,13,7,40
10/12/2009,42,55,0,1,14,7,40
10/13/2009,43,56,0,0,14,7,40
10/14/2009,44,56,0,0,16,7,41
10/15/2009,45,56,0,0,21,8,42
10/16/2009,46,58,0,1,19,8,42
10/19/2009,47,58,0,2,28,8,42
10/20/2009,48,58,0,6,26,8,42
10/21/2009,49,58,0,6,26,8,42
10/22/2009,50,58,0,7,25,8,44

Number three took less time but a bit of research because Perforce Java library’s API is not exactly straightforward.

It took me a while to figure out how to do the last one. After looking into JFreeChart and Google Chart API, I eventually turned to my dear friend, Tod Landis, who is also my partner at Entrance, and he quickly drafted an entrance script for me. Based on it, I was able to write a template that can be used for all teams within a few hours.


PLOT
  very light yellow  area,
  light yellow filled circles and line,
  DATALABELS
  very light orange  area,
  light orange filled circles and line,
  very light red  area,
  light red filled circles and line,
  very light blue area,
  light blue filled circles and line,
  very light gray area,
  dark gray filled circles and line,
  very light green area,
  dark green filled circles and line,
  all AXISLABELS
WITH
  ZEROBASED
  TITLE "Sprint"
  TITLE X "Days"
  TITLE Y "Points"
  SCALE Y 0 100 0
  CLIP
  legend
  gridlines
  collar
  no sides
SELECT
  `Open Bugs`,
  `Open Bugs`,
  date,
  `Open New Features`,
  `Open New Features`,
  `Open Stories`,
  `Open Stories`,
  `In QA`,
  `In QA`,
  `Deferral Requested`,
  `Deferral Requested`,
  `Closed`,
  `Closed`,
  day
from report;

Please note this is the final PLOT script, there are other SQLs run before this to import the data into the MySQL database, sum up the data to produce a stacked chart, and even out the labels.

And I now have this chart generated automatically every morning with the help of a windows scheduler.


Compiling Try/Catch/Finally on the JVM

One thing we’re currently working on, for a variety of reasons, is compiling down our in-house programming language into Java bytecode (and just for the record, I can’t make any promises about when we’ll be done or around when or even if this stuff will make it into future product releases).  Part of the fun therein is learning about the internals of the JVM, as well as finding all the crazy edge cases in your own language.  And few things are as, um, “fun” or have as many edges as try/catch/finally statements.  So rather than delving into philosophy or agile methodology this time around, I’ll go into detail on an area of the JVM that most people never have to (or probably want to) delve into.

If you’d asked me two weeks ago, I would have assumed that finally blocks are a feature implemented by the JVM:  it’s such a core language thing, it’s got to be built-in, right?  Much to my surprise, the answer is no:  finally blocks are implemented by inlining the finally code at all possible exits from the try or associated catch blocks, wrapping the whole thing in essentially a “catch(Throwable)” block that rethrows the exception when it finishes, and then adjusting the exception table such that the catch clauses skip over the inlined finally statements.  Huh?  (Small caveat:  prior to the 1.6 compiler, apparently, finally statements used sub-routines instead of full-on code inlining.  But we’re only concerned with 1.6 at this point, so that’s what this applies to).

That probably doesn’t make any sense, so let’s rewind a bit with some JVM basics around exception handling.  Exception handling is built into the JVM, and it’s done so in the form of declaring try/catch blocks within a given method.  What you’re saying is “between point A and point B, any exceptions of type E should be handled by the code at point C.”  You can have as many such declarations as you need, and when an exception is propogated to that method the JVM finds the catch block that matches based on the extent and the type of exception it handles.

So with a simple example:

public void simpleTryCatch() {
  try {
    callSomeMethod();
  } catch (RuntimeException e) {
    handleException(e);
  }
}

You might end up with bytecode like the following (I’m showing it in the format the ASM Eclipse plugin does:  it’s an invaluable tool for learning how the Java compiler works, and I find it’s formatting pretty easy to read.  The “L0” and such are code labels.):

public simpleTryCatch()V
TRYCATCHBLOCK L0 L1 L2 java/lang/RuntimeException
L0
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callSomeMethod()V
L1
  GOTO L3
L2
  ASTORE 1
  ALOAD 0
  ALOAD 1
  INVOKEVIRTUAL test/SimpleTryCatch.handleException(Ljava/lang/RuntimeException;)V
L3
  RETURN

So we’re saying the catch statement covers the full extent of the try block (though not the GOTO statement at the end), and that on a RuntimeException we should transfer control to L2.  If the try statement complete, it jumps over the catch statement and continues on.  When the RuntimeException handler is invoked, the exception is on the top of the stack, so we store it to a local variable slot.  We then load the “this” pointer and the exception argument in order to invoke the exception handler.  The catch block then falls through to the end; if there were additional catch blocks, it would jump over them.

So let’s add in a finally block and another catch statement and see what happens to the bytecode.  Suppose we have the following totally contrived method:

public void tryCatchFinally(boolean arg) {
  try {
    callSomeMethod();
    if (arg) {
      return;
    }
    callSomeMethod();
  } catch (RuntimeException e) {
    handleException(e);
  } catch (Exception e) {
    return;
  } finally {
    callFinallyMethod();
  }
}

In this case, we end up with this far-less-obvious bytecode:

public tryCatchFinally(Z)V
TRYCATCHBLOCK L0 L1 L2 java/lang/RuntimeException
TRYCATCHBLOCK L3 L4 L2 java/lang/RuntimeException
TRYCATCHBLOCK L0 L1 L5 java/lang/Exception
TRYCATCHBLOCK L3 L4 L5 java/lang/Exception
TRYCATCHBLOCK L0 L1 L6
TRYCATCHBLOCK L3 L7 L6
TRYCATCHBLOCK L5 L8 L6
L0
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callSomeMethod()V
L9
  ILOAD 1
  IFEQ L3
L1
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callFinallyMethod()V
L10
  RETURN
L3
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callSomeMethod()V
L4
  GOTO L11
L2
  ASTORE 2
L12
  ALOAD 0
  ALOAD 2
  INVOKEVIRTUAL test/SimpleTryCatch.handleException(Ljava/lang/RuntimeException;)V
L7
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callFinallyMethod()V
  GOTO L13
L5
  ASTORE 2
L8
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callFinallyMethod()V
  RETURN
L6
  ASTORE 3
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callFinallyMethod()V
  ALOAD 3
  ATHROW
L11
  ALOAD 0
  INVOKEVIRTUAL test/SimpleTryCatch.callFinallyMethod()V
L13
  RETURN

So what’s going on here?  (Note that the labels are numbered in the order they’re created by the compiler, not by the order they appear in the code). First of all, you’ll notice that both exception handler blocks are now split in two, from L0 to L1 and from L3 to L4.  That’s because the range from L1 to L3 is where the finally block is inlined due to the return statement.  Since exceptions thrown during the finally block shouldn’t be caught by catch blocks associated with the same try statement, that range has to be excluded from the exception table.  The exception entries with no type declared are from the finally block.  It has to handle any exception thrown from the try statement or from the catch blocks, but it also has to exclude any inlined finally statements so that the finally block doesn’t catch exceptions thrown by that same finally block.  It has to have three splits, because in addition to the inlined finally within the try block, the catch(Exception) block also contains a return statement.  You may also be surprised to see that the finally block appears a total of five times in the code.  You’ll see the first inlined finally from L1 to L3, corresponding to the return statement in the try block.  The second finally block is a bit more confusing:  in this case it’s being inlined into the end of the first catch block, which then jumps over the finally code that’s there in the fallthrough case.  (I personally would assume that it would jump down to the fallthrough case, rather than inlining the code again).  The third time it appears is from L8 to L6, around the early return statement within the second catch block.  The fourth time the code in the finally block appears is from L6 to L11, which corresponds to the exception case:  that’s to ensure the finally block is executed in the case of an unhandled exception thrown out of the try block or any of the catch blocks.  Notice that it stores the exception as normal, performs the call in the finally statement, and then loads and rethrows the exception.  The last finally block is for the fall-through case:  it’s where the end of the try block jumps to.

If we were to have nested try/catches or try/finallys, things would get even stranger.  A return from the inner try statement needs to have both the inner and outer finally inlined into it, and the exception table needs to be set up such that exceptions thrown by the inner finally are caught by the outer catch statements and the outer finally, and exceptions thrown by the outer finally aren’t caught by anything.  At this point you can probably start imagining the kind of state your compiler needs to carry around in order to know what to to inline where and how to partition the exception table correctly.

It’s interesting, for me at least, to see how the JVM designers chose to push the finally statement into the compiler rather than building it into the VM; clearly it can be built by the compiler, thus making the VM that much simpler, it just makes life a little rougher for folks like us who are building another language on the JVM.

Knowing how things are implemented by the compiler can actually make it a little easier to figure out what happens in certain odd circumstances.  For example:

try {
  return "foo";
} finally {
  return "bar";
}

will end up returning “bar” since the finally statement is inlined before the return statement, so the return from the finally block executes first and the original return statement never does.

String value = "foo";
try {
  return value;
} finally {
  value = "bar";
}

will return “foo” since the value to return is stored in the stack prior to the finally statement executing, and then restored and returned afterwards.  (My example didn’t show that, but that’s what you’d see if you were to look at the bytecode).  So the finally block changing the “value” variable has no affect on the in-progress return statement.  And lastly, something like:

while(true) {
  try {
    return "foo";
  } finally {
    break;
  }
}
return "bar";

will return “bar”.  This one surprised even me at first, but it makes sense once you realize that a break statement is just a GOTO in bytecode, so when the finally block is inlined as part of the inner return statement, that GOTO statement executes before the RETURN instruction and completely skips over it to the end of the loop (the same logic holds true for a continue statement inside a finally block).

On our end, we’ve decided to disallow return, break, and continue statements within the finally block due to the rather unexpected semantics (and C# disallows them as well, so I feel like we’re in good company with that decision).

If anyone actually found this enlightening, I’ll consider doing some future posts about other interesting issues we’ve run into when generating bytecode, both due to the JVM itself and due to the occassional impedance-mismatch between our language and Java around things like closures and enhancements and generics.


Concerning The Relative Stickiness Of Success And Failure

It’s often the case that the hardest things to get motivated to do are those with a very speculative chance of success.  If you put in a lot of time at the gym, you’re going to get in better shape.  If you spend time cooking, you’ll probably have some reasonable to eat at the end.  If you work hard at your job, there’s at least a pretty good chance that you’ll be rewarded for it.  For all those activities, there’s a straightforward and somewhat predictable correlation between effort and results.

Other endeavors, however, are far messier.  If you start a business, it’s likely you’ll spend a huge amount of time and end up failing.  If you really commit to a relationship, there’s always a chance that you’ll invest a ton and come away with nothing.  And the same generally holds true for most software projects, where it’s likely that you’ll build something only to find no one use it.  The amount of effort required to build a programming language, for example, is astronomical, yet the expected number of users for any new language essentially rounds to zero.

So how does one go about getting motivated to undertake an effort that’s likely to end in failure?  Well obviously, you have to be willing to fail, but how do you go about that?  At least one technique I’ve found is to focus on the fact that success is stickier than failure.

What does that mean exactly?  That means that success tends to last a while, but that failure is almost always temporary (and if it’s not . . . well, then you have a different set of tradeoffs to consider).  It might take you three or five tries to start a successful business; so what?  A successful business can last for decades, potentially.  Your heart gets broken; so what?  If you keep trying, odds are good that some day you’ll end up in a stable, long-term relationship.  No one uses your open-source project, or the product managers don’t like how you’ve implemented a feature.  So what?  You figure out why not and try again, or perhaps you’ll find some existing project to devote your energies to instead.  Eventually, chances are you’ll hit on something worthwhile, and that project will stick around for a long time and deliver more than enough utility to compensate for the effort seemingly wasted on the failed efforts.

Of course, that theory only works if the cost of failure is mainly the loss of the associated resources; if you’re in a position where trying to force some new internal project on your organization could kill the company if it fails, the set of tradeoffs is a bit different.  But usually that’s not the case; people are usually much more worried about feeling like failures, or about wasting time and resources, or about the way their friends or their family or their managers will react to them if they fail.  But the funny thing is, once you have a success or two, no one really remembers the failures, because they’re so transient when compared to the successes.  No one remembers that it took you three tries to really nail some feature; all they remember is that you nailed it, and that it’s so good that no one has to touch it anymore and you can worry about different things.  And no one remembers all those stupid ideas for internal projects that you’ve had and abandoned over the years, they just remember that one awesome idea that you had that’s become totally indispensable to the company.

Failure is a temporary condition, a mere rest stop on the way to success.