In part one of three, I covered the basics of making a quickfix pattern for a bug - starting with parsing the Abstract Syntax Tree (AST) and ending with creating a new ASTNode to replace the broken code. In part two, this tutorial, we will be tackling a slightly more complicated bug that needs resolving: Randoms are not super secure. In cases where they need to be less guessable, it is better to either use a SecureRandom (at the cost of speed), or simply initialize a Random with a long from SecureRandom (mitigates time-based attacks and faster, but still not super secure).

The user will have to decide which one of the two suggested fixes applies, so we need to give them a choice. This tutorial will show how to offer two quickfixes as well as customizing the descriptions to give more information.

One Weird Random QuickFix Recipe (that will totally be clickbait)

Preparation time
5m
Coding time
10m
Difficulty
Hopefully getting the hang of this
Serves
A light airy second course, before the rich desert

If you've already done the first part, you should have an Eclipse project setup already. Otherwise, download this preconfigured Eclipse workspace and then install the dev version of FindBugs from here.
If you want to do this in hard mode, follow the dev setup instructions for fb-contrib quickfixes - it will amount to basically the same thing.

Registering two quickfixes for the BugPattern MDM_RANDOM_SEED

Just like last time, we'll start by modifying the plugin.xml file. The main difference you will notice is that we register two fixes for the same resolution. This will make both fix options pop up on the list of resolutions.


        
These are the arguments that differentiate the two fixes.
Everything should look similar to the first fix, with on addition, highlighted on lines 8 and 15. These arguments will allow our code to differentiate between which of the two fixes. An alternative approach would be to make two classes for each fix, but that seems inelegant and prone to code duplication, especially for the visitor.

Making the two fixes

To make two separate fixes, we'll need to override setOptions() to distinguish between them and then code in the separate fixes.


        
We will need TypeBindings for the visitor implementation below. This method handles the parsing of any arguments you pass in. The arguments will be parsed as comma-separated, if you need more than one. And we simply use the parsed argument from above to determine the fix to apply. This call is from the FindBugs plugin.eclipse.quickfix.util.ASTUtil class and will add, if it doesn't already exist, a reference to SecureRandom. This is a simple way to create a constructor invocation of SecureRandom. One downside is that it won't deal with imports, potentially leaving a compilation error. Line 31 corrects this oversight. Makes a call to new Random() Chains a newly created SecureRandom to a call of nextLong: new SecureRandom().
nextLong()
Takes the output of the long generated from the SecureRandom and uses that to initialize the Random object we made in 42-44.

The only tricky part to this so far is the creation of the new ASTNodes. Remember that ClassInstanceCreations are when a constructor is called (i.e. a class instance is made). Do not be tempted by the (more logically named) ConstructorInvocation.

Making the visitor

This visitor is very straight forward because we only have to look for when a Random is created.


        
node.resolveTypeBinding() gets the type of the object. We simply look for the java.lang.Random type.

Showing Custom Descriptions

The last piece is supplying custom descriptions, which simply involves overriding the aptly named getDescriptions method.


        
The only trick to the descriptions is that you should use <br/> for line breaks, as the message will be interpreted as html (or some subset of html).

Conclusion

This example showed a slightly more involved quickfix, with two options. Next time, for the last of the three parts, we'll go all out, looking at an example with custom labels and complex type logic.