Thursday, April 29, 2010

nbgit for NetBeans 6.9 beta

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


My brother was asking me for a version of nbgit (git support for NetBeans) that works with NetBeans 6.9 beta. I've uploaded one here. By the way, look at the Options wiki page, and especially the sections on Custom Actions, for useful configuration tips for nbgit.



Wednesday, April 28, 2010

IDE tip: Go To Implementation

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


One of the best parts of using an IDE instead of an editor is "Go To Declaration". When you hold the Control key (or the Command key on Macs), identifiers under the mouse turn into hyperlinks and when you click on the hyperlink you jump to the declaration point of say the method call.
You can also just hover over the hyperlink, and a tooltip will pop up and show you the signature of the identifier - the fully qualified type name, method arguments, and so on.

But what if the thing you are pointing at is an interface? Or an abstract class? Good Java programming style dictates that you should prefer interfaces over implementation types, so your code will typically only know about the interface or abstract type, and when you jump to the declaration, you go to the boring interface method definition, rather the interesting bits in the implementation!

This is what the Go To Implementation feature is for. And I have a confession to make: I didn't start using this until recently. At the recent IDE tips roundup session, somebody asked whether NetBeans supported Go To Implementation. By instinct I went to Google and looked for a NetBeans plugin to do it, and found one. Unfortunately, it was old and only worked with older versions of NetBeans. Uh oh. Then on a whim I decided to look in the Navigate context menu in NetBeans - and lo and behold, it's right there!



And you don't need to use a context menu to access this feature. The trick is to use a second modifier key to the normal ctrl-click on the identifier! In addition to the control key (or command on Macs), also hold the Alt key (Option on Macs).

Here's how it works. First, let's say you want to go to the actionPerformed implementation. You ctrl-click the identifier:



...and that takes you into the abstract method declaration. (In this specific case, the method is in a read-only file inside a .jar file, which is why NetBeans marks the whole file in gray)



That's not what we want. Go back to the previous editor location (Ctrl-left.) This time, hold both the Control and Alt keys (or Command and Option on Macs) when you click. When you do that you get this dialog:



This dialog has focus and you can use the arrow keys to navigate and press enter -- or just click with the mouse. As soon as you pick a specific override of this method, you jump to it:



That's all there is to it. It's doubly embarrassing that I didn't remember this feature, since I should know the implementation of it very well. You see, I shamelessly lifted most of the implementation of it for the language-infrastructure work I did to support Go To Declaration in Ruby, JavaScript etc:



P.S. I've updated the wiki page with a clarification that it's built in now.

P.S.2: Until recent builds, Go To Implementation in NetBeans only worked for interfaces, not methods extending abstract classes. So use 6.9.


Tuesday, April 13, 2010

IDE tip: Create Build and Execution Shortcuts

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


We're moving over to Oracle's mail and file storage, so I spent a couple of hours going through my old Sun home directory to see what I wanted to save. It was pretty fun coming across all kinds of old screenshots, source code and design documents for things I worked on 10-15 years ago.
I spent the first 5 years working on Sun's C/C++ development environment, and in particular the debugger. One feature I built was the ability to create custom buttons which would let you run frequent dbx commands (as well as reference builtin actions). Here's one screenshot I came across.


The CDE/Motif widgets look pretty dated







Anyway, this reminded me of another really useful feature in NetBeans: The ability to create custom shortcuts for ant targets. If you're using ant, you probably have a number of useful, extra build targets. One I find particularly useful for our setup (where we have lots of project dependencies) is to have a "just run" build target which skips all dependency checks and just runs whatever bits are there. This is particularly useful if I change something in an upstream project and I don't want any checking downstream.

Here's how you do it. First, let's say I've created an ant target to

Target ideas: Run findbugs. Run code coverage. Run an arbitrary script.

Thursday, April 1, 2010

How to Write a Memory Leak Unit Test

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Unit tests are great for ensuring that your functionality is correct. But how do you make sure you don't have leaks in your code, leaks that
eventually cause your application to crash when it runs out of memory? Unit tests don't typically don't run into memory problems directly because they tend to start up, run a little bit of code, and shut down -- getting a nice fresh memory environment on each test start.



One great way to help protect yourself from uptime problems is to write leak tests. These are unit tests where you first perform some operations, then do normal cleanup, and finally you assert that the objects you were using during the operation have been cleaned up completely. In other words, that there are no references left anywhere on the heap.



Testing for leaks isn't very hard; the basic trick is to create a weak reference to your to-be-cleaned object (by constructing a WeakReference wrapping your object), then you delete all your local references to the object, then you perform garbage collection, and finally you see whether the weak reference still contains your object. This works because the weak reference is handled specially by the garbage collection system.



It turns out things aren't quite as easy as that, because garbage collectors try to be smart, and simply calling System.gc() doesn't mean it's going to actually perform a complete and final garbage collection. This means that your unit test could incorrectly conclude you have a leak, since the reference is still held.



The NetBeans team has built a really good test infrastructure for this. When I wrote unit tests for NetBeans plugins, I could simply call their assertGC method to assert that the given weak reference should be garbage collected, and it would handle the rest. (Internally, they do things like actually allocating a bunch of memory chunks to really force the garbage collection to run.)



Here's an example:


// The following unit test fragment wants to ensure that a graphics object
// which shows the current selection in the authoring tool, is cleared up after
// the user clears the selection.
view.selectAll();
Node firstHandle = /* Node showing selection highlight, lookup code here */;
assertNotNull(firstHandle);

// Now clear view selection -- then assert that all the handles have disappeared
view.selectNone();

WeakReference<Node> ref = new WeakReference<Node>(firstHandle);
firstHandle = null;
assertGC("Selection handle leaked", ref);



When you write these tests you also have to make sure you null out any local variable references you are holding right there in the test.
The above test will pass if and only if the target object, firstHandle, is properly garbage collected.



But wait -- that's not the best part. Let's say you've written a leak test, and it fails. Now what? What do you do -- make the process pause and attach a profiler and try to hunt it down?



This is where their unit test support really shines. When the unit test discovers that the reference is still held somewhere, it uses its own heap walking library to hunt down the offending reference, and dumps it out as part of the test assertion failure message!!!



Here's the output of a real leak test failure:


Testcase: testMemoryLeak(SelectionHandlesTest): FAILED
Selection handle leaked:
public static java.util.List javafx.scene.Scene@dc8a29-$dirtyCSSNodes->
java.util.ArrayList@4ed14172-elementData->
[Ljava.lang.Object;@3c22de9e-[41]->
javafx.scene.shape.Rectangle@612e4cd

In other words, we see that there is a static list in Scene named dirtyCSSNodes which is holding on to our target Rectangle. The syntax here is that you first see the class name for the object (where a prefix of [L means it's an array-of), then its system id, then the field name - and if it's an array, the array index.



When the unit test fails, it takes a while -- 20 seconds or so for the above test -- to actually produce the above trace. But the important part is that this is only slow when the test fails. It only has to work hard when you have a leak, and you don't want to have leaks!



I've been wanting to write leak tests for the authoring tool (which is written in JavaFX), since uptime matters a great deal in a tool which deals with potentially large objects (such as multimedia assets). And I realized that there is absolutely nothing NetBeans specific about the NetBeans leak unit test support. So I went and pulled out the relevant code into a separate library. The library basically contains two parts: a .jar file which contains the INSANE heap walking library, and a second jar which contains the assertGC() unit test assertion method and supporting infrastructure.



I have extracted this into standalone pieces (outside the NetBeans infrastructure) so you can get the bits easily - download leaktests.zip, then add the two jars in there on your test classpath and call assertGc() and assertSize() from your tests as described above. Here's the basic skeleton for all leak tests:


// (1) Create your objects
// (2) Look up the object you want to ensure gets cleaned up later:
Foo foo = // code to get foo
assertNotNull(foo);

// (3) Call your cleanup code which is supposed to free everything

// (4) Create a weak reference to your object reference, and null out
// your reference
WeakReference<Foo> ref = new WeakReference<Foo>(foo);
foo = null;
assertGC("Foo leaked", ref);



All I've done is extract NetBeans code written by others so I've kept the licenses the same as for NetBeans. All credit goes to the author of INSANE, Petr Nejedly -- and to the authors of the memory assertion stuff in NbTestCase.java. All the source code for INSANE and NbTestCase are in the NetBeans mercurial repository.



In addition to assertGC, there is also assertSize(). This method can be used to ensure that the transitive size of an object graph is below a certain threshold! This can be good for writing tests to not only ensure that you don't have leaks, but that your data structures are of the rough expected size so you don't need excessive amounts of memory. There are more details on this on the INSANE home page.



One special note on JavaFX: The above leak isn't actually a leak; it is a deliberate optimization of the scenegraph, and the reference will be cleared up after the next scene pulse completes. Therefore, for unit leak tests, in addition to actually nulling out the weak references, you also want to run through a scene pulse as well. One really hacky, implementation-dependent and unsupported way to do that is to call scene.$scenePulseListener.pulse();. You probably want to isolate that in a utility method such that you can update it in one place when it needs to change...



Finally, note that I built this on JDK6. If there is interest perhaps we could create a wrapper project for this on Kenai or java.net, where people can also create say a Maven binary for this, a JDK 5 version (there is nothing JDK6 specific so it just needs a recompile, but I don't have JDK5 on this Snow Leopard Mac), etc. Hope you find this all as useful as I have!


Tuesday, March 30, 2010

IDE tip: AST-based Selection

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


AST-based selection is a feature which lets you select the surrounding "block", based not on syntactic clues (such as braces and parentheses, as is offered by practically all editors), but based on the parse tree created by the compiler (or the "AST", for abstract syntax tree).

In NetBeans, there are two complementary actions to deal with AST selection: Select Surrounding and its reverse. They have other names which I can never remember, but the keybindings are as follows:

Select surrounding block


  • Mac: Ctrl-Shift-. (period)
  • Windows/Linux/Solaris/Others: Alt-Shift-.

Reverse:

  • Mac: Ctrl-Shift-, (comma)
  • Windows/Linux/Solaris/Others: Alt-Shift-,


On my U.S. keyboard, the comma and period keys are marked with "<" and ">" for the shift key which is somewhat reminiscent of blocks.

These two actions cooperate and are stateful: they remember the original caret location such that you can "go back".
Here's how it works. You want to select something surrounding the caret, say the whole method. In that case you just
hit the surrounding action. With your fingers holding ctrl and shift you hit dot -- once, twice, bam bam bam. If you do it
quickly you might "overshoot" and go one too far and select say the whole class instead of just the method. If so just press
comma and voila, it goes back one step down the selection hierarchy you just came up.

This makes this a very quick way to select code blocks -- no more need to grab the mouse and try to hit exactly the selection
boundaries between characters.

Here's an example of where this comes in useful. I sometimes remove long expressions from method call arguments by pulling it
out as a separate variable. Here's my call, and I want to extract the whole Math.min expression.
First I move the caret anywhere within that expression:


Then I press Alt-Shift-. (or Ctrl-Shift-. on Mac):


One more time:


Let's pretend I was doing it quickly and hit it one extra time:


That's too far, so I press comma (with the modifier keys still pressed):


In practice (and with practice) this is done very quickly, faster than I can
accurately hit both ends of the expression with a mouse drag. And to finish
out the example, let me show a couple of more things related to the task.
Notice how there's a light bulb in the left hand side margin of the editor.
That tells me there are associated quick fixes. I press Alt Enter,
and the quick fix dialog is shown:


I choose "Introduce Variable" and press Return. This gives
a dialog where I can choose the variable name (and whether to replace all occurrences
when applicable). It suggests "min" since that's the function
name of the expression we're extracting.


Just press Return to apply the refactoring, and we've pulled out the argument
expression:


I just pressed return and got the default name. Then I realize that this may
not be a great name. What is that last parameter again? I can place the caret
somewhere within the last argument and press Cmd-P (or Ctrl+P
on other platforms) to get NetBeans to "Show Method Parameters".


Let's rename it to length instead. Press Ctrl-R (all platforms) to
apply rename refactoring, which (because this is a local or private variable)
will have "instant rename" applied where your edits are applied immediately
for every keystroke:


Just type the new name - notice that all the boxed expressions are edited synchronously.


Using AST-based selection to identify code blocks to extract as variables or methods
is useful, but it can be used in other ways as well. Let's say I want to add
a second validation step to this function. First I select the code block using
AST selection:



NetBeans has a keyboard command for duplicating the current line: Ctrl-Shift-Down
(and on Mac, it's Cmd-Shift-Down.) Note that when you have a selection, this
duplicates the entire selection. So all we have to do now is apply the duplicate command
and we've got a second if clause we can just tweak to whatever it is it needs to do.



AST based selection should be available in nearly all editor types in NetBeans.
In Ruby, JavaScript, Python, etc it also handles documentation
blocks well - so if you apply select surrounding in say a Ruby comment, it will first select
the current line, then the whole documentation block, then outwards in the AST hierarchy.

Hope you find this helpful. If there are Eclipse or IntelliJ readers who know corresponding
keybindings in Eclipse, feel free to leave a comment so others can find it easily.



Thursday, March 25, 2010

IDE tips

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


One of the sessions we had at the Roundup was one entitled "IDE tips and tricks". We basically sat there with our laptops and did a show & tell of various "hidden" IDE features we knew about to help productivity. There were Eclipse, IntelliJ and NetBeans users there - and even some advocacy for Vim :) We discovered pretty quickly that this would not make for compelling listening, so we just turned off the recorder.



One thing I discovered (and which I saw during our languages coding dojo day as well) is that a lot of people don't use many of the productivity boosters. Therefore, I thought I'd bring some of these up here. Since I've been intending to start blogging more again, I'll make this a regular "column".



To kick things off, I'll just point to an old blog entry which is still relevant: Hippie Completion. Learn to use Ctrl-K while editing, it will be worth your while. (Eclipse has this too as of Eclipse 3.1; I believe it's bound to Alt-/).


Transparent windows on Linux

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


JavaFX makes it easy to create non-rectangular windows -- just set a StageStyle.TRANSPARENT on your stage.style.
We use rounded corners on our popup menus, and we also have a non-rectangular and alpha-blended splash screen.

The other day I was checking how the cursors were looking on different platforms, and imagine my horror when I discovered how our new splash screen and rounded menus looked on Linux! Here they are -- as you can see you end up with white rectangles around the supposed-to-be-blended areas:





That looks.... craptastic!

Historically, the JDK didn't support alpha blended windows on Linux. However, that was added a while ago (I'm not sure exactly which version, but I think it was JDK 6 update 14). It turns out that the FX code which initializes the native frame for the stage does not do conditional checking for this; it simply turns off transparency on Linux. Fortunately, there's a System property you can set to force it to respect the transparency flag. You would obviously only do this if you know you are running on a JDK which supports transparency. And that's easy!

In your startup code, do something like this:


if (Utils.IS_LINUX and Utils.jdkAtLeast(1, 6, 0, 14)) {
java.lang.System.setProperty("javafx.allowTransparentStage", "true");
}

There are a couple of utility methods here that are simple - just looking at some system properties to determine whether we're on Linux and whether we're on a particular version of the JDK or higher (if you run on non-Sun/Oracle JDKs you may want to check for that as well).


public def IS_LINUX = osName.contains("linux");
public def IS_MAC = osName.contains("mac");
public def IS_WINDOWS = osName.contains("windows");
public def IS_SOLARIS = osName.contains("solaris");

/**
* Is the version of the running JDK at least major.minor.micro_update?
* In 1.6.0_18 macro=1,minor=6,micro=0,update=18
*/
public function jdkAtLeast(macro: Integer, minor: Integer, micro: Integer, update: Integer): Boolean {
def runtimeVersion = java.lang.System.getProperty("java.runtime.version");
def pattern = java.util.regex.Pattern.compile("^(\\d)\\.(\\d)\\.(\\d)_(\\d+)-");
def matcher = pattern.matcher(runtimeVersion);
if (matcher.find()) {
def currentMacro = Integer.valueOf(matcher.group(1));
def currentMinor = Integer.valueOf(matcher.group(2));
def currentMicro = Integer.valueOf(matcher.group(3));
def currentUpdate = Integer.valueOf(matcher.group(4));
if (currentMacro < macro or currentMinor < minor or
currentMicro < micro or currentUpdate < update) {
return false;
}
}

true
}

With that modification at startup, we get much nicer results:





P.S. Yes, there's a JIRA issue tracking this to be automatically done by the platform, RT-4797.

P.S.2. This is for desktop; I'm not sure this code is mobile-safe.