How can you improve your Java development workflow with Facebook’s Infer?
If you keep in the loop with tech buzz (which I’m assuming you do if you’re reading this blog), you’ve likely heard about the new tool Facebook just released to the public: Infer. Since it came from Facebook, people are naturally curious, so I wanted to take a look at what the tool’s about and how it could play a role for Java developers.
— Takipi (@takipid) June 24, 2015
What is Facebook’s Infer?
Before assessing its potential usefulness, the first step is of course to get a sense of what the tool is and does. Infer is a static analysis tool that Facebook recently released as open source. Designed for iOS and Android usage, it can be used to detect bugs in your application before it ships. Facebook’s engineers have been using Infer as an internal tool on its Facebook and Instagram apps, so it’s been well vetted for high scale mobile environments.
Roughly, the way it works is that it scans your code during compilation looking for certain pre-conceived bugs and error conditions. After capturing information on your compilation process, it analyzes it in search of potential bugs. If it finds any, it will report them to you in your terminal and write them to a directory file. Examples of the types of bugs it looks for are null pointer exceptions and resource leaks.
Setting up Infer requires Python 2.7 and either Mac OS X or Linux. To run it, you can use javac directly or go through build tools like Maven or Gradle. Here’s an example of what it looks like in action:
In this example we can see how Infer identifies a simple null reference, outputs the relevant information we need to fix it, and successfully passes the class after the fix is saved. The full source code for Infer can be found on Github.
Incremental vs. Non-Incremental
Infer can be run in either an incremental or non-incremental manner. The difference between the two being whether or not Infer will delete the existing results directory or not. So for example, you might want to run incrementally when using a build system and non-incrementally when using a single compiler command. To allow the incremental mode, you just need to add the –incremental flag.
As far as limitations go, Infer faces several that are standard to static analysis tools. It can report false alarms and/or miss bugs based on how your application has been coded and how it interacts with 3rd party code. There is also a limited scope of problems that it can detect, as it can’t test your code in a dynamic manner. There are also technical limitations around the types of bugs that it tests for. For example, Infer doesn’t test for array bounds errors or cast exceptions today.
What could this mean for Java developers?
Infer was designed for mobile usage, but it works perfectly fine for plain Java as well. As it can be run from build tools like Maven, it’s not a stretch to fit it into your workflow. The question of course is whether or not it’s worth using.
The answer to that question comes down to your stance on static analysis tools. Infer is obviously not the first static analysis tool that works with Java (FindBugs is a popular one for example), nor the only open source one. It is the only one that’s come from Facebook however, which may carry a certain cache with you. With established usage by Facebook on their giant apps, Infer has been put under fire for high scale.
There are some language limitations for Java that Infer faces however. It isn’t able to handle Java’s Concurrency Utilities or features like arithmetic. Some of these issues are trouble for other static analysis tools as well, but it’s worth keeping in mind.
Static analysis tools in general fit in the in-between phase of development. They’re essentially a testing tool for the staging step of the development process or as part of a CI/CD workflow. They can’t replace debuggers in development, since the code has to compile for them to work, and they can’t replace error trackers in production, since a whole host of bugs only show up once code hits the production environment and exposed to dynamic inputs. But there is a space in between those two environments where a tool like Infer could be useful.
For example, you may choose to use Infer as an intermediate step along with your IDE of choice for your development environment and Takipi for your production environment. Infer can help in this situation to pre-catch some obvious bugs before they go into production. This can prevent a few issues for your users or at the very least cut down on some entries in your Takipi dashboard. Or if you’re running a continuous deployment model with Jenkins, you can run Infer after each release push to see if anything new throws up obvious red flags.
When a company like Facebook releases an open source tool that plays well with Java, it’s worth giving it a look over. Infer isn’t built for Java specifically, but it can be used for static code analysis in Java apps nonetheless. There are some definite limitations to it, but there also some good potential uses for it and it’s something that should continue to improve in the future. If you play around with it, let me know what you think in the comments.
Using the right tools is critical to success, to make sure you’re covered when your code ships out to production, check out the alerting tools chapter of the definitive guide for production tools.