Java.sun.com (JSC): How many bugs did you fix in Java SE 6? Harry: I actually don't know -- I've probably submitted a multiple of a hundred. What's important is not how many you fix but getting into the code. I can't see someone being motivated by thinking, "I'm going to do 500 bug patches." Wanting to devour the code is a much stronger motivator. I like to get inside things and see how they work. You can read the code and learn about it that way, but if you want to make it instinctual, you need to work with it. JSC: Did you also spend time finding bugs?
Harry: Yes, I would start with a simple question, such as "Do any classes return internals and violate encapsulation?" Then I'd write a test case testing each Swing widget. Sometimes things would fly. Other times I'd find problems. Also, I look at the bug database for a matching bug report as a natural part of doing any request for enhancement (RFE) or bug fix. When you find something wrong, it's important to see if there's a matching bug report. While researching a MDI (Multi-Document Interface) RFE, I had serialization problems during testing. I found a bug report that seemed to match what I saw, so I wrote a fix for it and tested the code with the fix in place and voilà, things worked. JSC: Lots of people find bugs, but only a few seem willing to dig in and fix them. What motivates you to fix these bugs? Harry: Bug fixing is a great way to understand how the code works. Reading the code is fine, but working with it is better. Even if you don't find a solution, you'll learn and become a more powerful developer. Just think of times when you were faced with an API that made
sense, but you had trouble getting it to work. If you cross the
Javadoc boundary into the source code, your chances of success
increase. For example, I helped someone on java.net find an
acceptable solution to the " Bug Tips
JSC: Are there any tips you can share? Harry: First, always acquire the test that's attached to the bug report. The state of the bug database is a mixed affair. Sometimes the test is visible, sometimes not. If you're impatient and decide to build a fix based on the report because the test isn't visible, you may waste your time trying to recreate the problem. In several cases, after I reviewed the test, it became apparent that the report gave the wrong description of the problem. Next, ask yourself if it's really a bug. In some cases, the reporter would have been better off getting help from a Java forum. Moreover, sometimes the test case was buggy. Once you confirm that it's a bug, you dig in. The best way to be effective is by being familiar with the source. Also, writing down my thoughts as I seek a solution helps clarify the problem and documents the history if I need to revisit it. Including your reasoning processes in your patch helps communicate with whoever evaluates the patch. And consider writing multiple solutions. Your solution may work, but it may not be optimal. In a similar vein, be prepared to iterate on your solution. It may seem to be a good solution, but unanticipated issues can trip you up. As to writing unit tests, look at what the patched code interacts with. This may entail viewing a lot of code, but it's necessary to test the different paths to the patch. Swing Tips
JSC: Do you have any Swing tips? Harry: Yes, try to be comprehensive in testing the patch with
different looks and feels (LAFs). Much of Swing's behavior depends
on the LAFs, so ignoring any of them because you never use them
amounts to ignoring the central clients of Swing. What good is a
patch for Also, make sure that the test case is running on the event dispatch thread (EDT). If it isn't, you may not have a bug, but instead just have bad programming. There are exceptions to this rule, for example, on a non-EDT thread:
The only reason I'd do something like this is because the Javadoc explicitly states: "Is Thread Safe." In this particular case, I've used this with asynchronous colorizers. If it wasn't thread safe, you'd risk ending up with a deadlocked Swing application and a negative perception of Swing. Understanding threading is necessary for Swing programming. Though the application framework might make this easier, currently, to do anything serious, you need to be able to think with threads. JSC: Why did you fix so many bugs in Swing? Harry: I gradually evolved into doing it. I started scouting the Swing forums for help, which in turn led me to helping other people. During a discussion about making Instead of helping one developer, leverage your work and help everyone. JSC: What makes a good bug fixer? Harry: Someone who's a researcher and doesn't quit when things initially go wrong. Here's an example. I was flummoxed by this byte-code sequence:
It seems simple, setting a local variable to the integer 100. But
the verifier blew up because I never truly appreciated how much the verifier does for the Java developer until I started working with byte codes. If you're new to it, you quickly learn what a strict taskmaster it is. It may have driven me mad for a while, but I was able to sit down with the VM spec and come up with a rationalization of the problem and a subsequent restructuring that worked. Likewise, if you're doing a Java code fix, don't just look at the current version of the platform. I've routinely tested out bug tests on 4.0, 5.0, and 6 to investigate when a problem started and stopped. See if you can find why something started. My "uninitialized" problem has roots in the verifier spec. JDK bugs will have roots in some historical moment. Getting a bigger picture may provide clues about the design factors that led to the bug. Swing Developments in Java SE 6
JSC: How do you feel about Swing developments in Java SE 6? Harry: There are some cool things in Java SE 6: better native LAF
fidelity, Java SE 7 looks much more exciting. The application framework could change how future Swing apps are written. If I can just do this:
and have it produce an Anyway, if the trend is to get rid of the boilerplate, it seems good. Why should you as a developer always end up defining a new class when all you care about are the guts? If at some point you need to reuse something, just whip out the lovely Java refactoring "Extract Class From Annotation," and you're set. A Fun Bug Fix
JSC: Can you give us an example of a bug fix you enjoyed? Harry: The ultimate fix wasn't exciting, but I enjoyed finding and writing a fix for a Java crasher that was located in the GTK code. In a nutshell, if you changed the GTK Theme, your Java instance would crash. So the journey started out in the GTK LAF, went into its native code, and eventually deposited into the GTK widgets that are used by Swing to do its nifty rendering. The Solaris DTrace facility was great at providing more detailed information about the crash. It was my first time using it, and I was very pleased with it. Without DTrace, all I got was an error message. The GTK text widget's cursor started blinking because of the theme change. The widget's code is designed to abort or toss an assertion if it's blinking, and it didn't have the focus. So the fix was: Don't let it blink. Odd but true. I'm glad Swing doesn't do such things. Swing lets you be weird. It was a simple fix but an interesting journey down atypical paths. JSC: You're probably very familiar with the Java source code at this point. What advice do you have for those who are just starting to look at the source code? Harry: For Swing, map out the relationship between the Swing class and
its UI. To be an effective Swing hacker, you need to know what's
coming from what. As to robustness, Testing, Testing, Testing
JSC: How do you go about testing your fixes? Harry: I like tests to do two different things. I'll have a non-GUI
method that's a set of Surf the Bug Database
JSC: Is there a book or article on bug fixing that you recommend? Harry: The book I'd recommend is Code Complete. It's convinced me of the limitations of unit tests, which does not mean you shouldn't do them. But you need to complement them with code reading and other things. I'd recommend surfing the bug database, especially for the subject area that interests you. This may not hold true for areas such as the VM, but it's indispensable to become better acquainted with what has been bugging Swing. It may also help you gain a more general sense of a particular problem. Look at the "Swing models need pre and post listeners" bug. It probably has one vote for it. But in reality, it manifests itself over and over again in other little bugs. I've written patches for bugs that have fallen into this category with the recommendation that you either put the patch in or close the bug and reference the "pre post" bug report. This problem has acted as a force in the Swing library as well. Take a look at Of course not, but it's fun to dream. When Not to Fix
JSC: Are there some bugs you shouldn't mess with? Harry: Sometimes nontechnical factors cause problems. I dealt with a bug for mixed enabled widgets and the cursor, and I worked out a fix on the UNIX side. Since this was in the secret AWT code, I had to look at what was on the Windows side. The Windows code looked remarkably similar to the UNIX code but was in C++. Since I didn't have a $1000 Microsoft Visual Studio to build Java on Windows, I didn't submit a patch. I believe the compiler requirements have changed, so I might be able to revisit this someday. Another showstopper is when an external component is buggy. For
example, there's a bug I would describe as "GTK,
I also haven't fixed text/caret bugs that mix right to left and
left to right text. Usually when I start working on a bug, I snip out
any evaluation by the engineer and start from scratch to see if I can
reach some common ground. After considerable analysis, I've concluded
that the problem is due to two significant pieces with conflicting
I found one method that appeared to do the wrong thing, so
altering that repaired some problems. But ultimately, it didn't solve
the problem because there was still conflicting My Pet Bug
JSC: Do you have a favorite bug story? Harry: I don't recall the particular bug, but someone on java.net complained about a problem and put out a bug report. I put a fix together and submitted it. Then, rather quickly, a Swing engineer folded it into the code base. Though the technical aspects aren't exciting, I feel gratified that different members of the Java community can work together and accomplish things. With open sourcing of the Java language, perhaps this will become a trend. To empower yourself, you need to get involved. The Potential of Open Source
JSC: How do you feel about open source? Are you involved with the OpenJDK project and JDK 7? Harry: Open source has significant potential for Java developers, depending on community involvement. Regular users who aren't that involved with the language itself may prefer to regard the Java language as a building block only. Yet a part of the community actively called for it to be open sourced. It's happened, so now what? Are these folks going to contribute and collaborate? Time will tell. I look forward to seeing what the Java SE 7 application framework can do. Looking at the source, reflection appears to be one of its tools for getting work done. Maybe rather than reflection, runtime class generation could be utilized instead? It would be more efficient -- though is it necessary? -- and may lend itself to making the framework do more than it's capable of now. I've been playing around with class generation for the last couple of months, so I'm curious to see if I can fuse the Swing/byte code so that they're spinning together. JSC: What enhancements would you like to see? Harry: I'm excited about superpackages and method references at the language level. Superpackages hold the promise of eliminating some crude hacks to get cross-package interaction working without breaking encapsulation. We'll have to see about method references. I like the freedom that passing methods around could introduce, but I don't like the idea of sacrificing clarity to do this. Will it be implemented as a new construct, or will it be one of these sneaky compiler tricks? I don't know. At the VM level, I'm excited about This is great if you're engaged in Java programming, but what if you're running a language on the VM that's a little less smart? Take Jython, for example. In its implementation, the PyObject, which is central to Jython's running, has something like 150 methods. Why are these methods there? Probably because it would be nonperformant to look up each one of these when you need to execute. Maybe Hopefully in the future, a limited form of multiple inheritance will exist. I don't particularly care about being able to express this at the Java language level, but it would be powerful if I could generate a class at runtime and have it inherit a chunk of code in a very constrained manner. I'm not too hip on introducing inheritance diamonds into the system, but there are days when the "implement an interface and delegate to a common implementation" design doesn't scale very well. Gosling: "Perhaps You're Looking in the Wrong Place"
JSC: On his blog, James Gosling, after struggling to fix a bug, describes one of the most important rules of debugging: "If you don't see the bug where you're looking, perhaps you're looking in the wrong place." Any comment? Harry: That makes sense. I'd add my own rule: "The place where you find bugs may not be the right place to put a fix in." Why is this method being fed I wouldn't do that -- I'd do some digging and find the root cause.
If you simply patch it in a specific place, it doesn't prevent
Solving One Problem and Creating Another
JSC: So solving some problems can create others? Harry: Yes, a Look at A common theme in bug reports is that different people want
different things. Take Swing's JSC: Any closing thoughts? Harry: Tell your boss you'd like to spend some of that training time fixing JDK bugs. Not only will you fix that annoying bug, but you will become more of a JDK expert, which is the point of training, isn't it? See Also
The OpenJDK Project
| ||||||||||||||||||||||||||||||||||
|
| ||||||||||||