Kengo's blog

Technical articles about original projects, JVM, Static Analysis and JavaScript.

Impact of error-prone

Findbugs is really good solution to improve quality of code

As an author of findbugs-slf4j, I really love Findbugs. It lets us find problems by static bytecode analysis. This tool improves quality of each module, reduce reproducing known bug, and point problem quickly in IDE. We do not have to use code review to find known problems and/or antipatterns, Findbugs will do it before developer sends pull-request. This 'push notification' is really cool, we can point problem even if developer has no motivation to find it.

It is really ideal solution also for large scale development team. Even if your team has hundreds developers, they can get help from Findbugs from the beginning of working day. Even though some of them have less experience and knowledge about our depending framework, module and language, Findbugs can help them to catch up quickly.

Findbugs is constructed based on both academic and practical experience, and now it's OSS so not only limited contributors but also everyone who wants to improve documentation comment, message translation, new detectors and so on.

Problems in Findbugs

But I have a dream to implement Findbugs alternative, to replace Findbugs with better implementation. In my personal opinion, it has some problems:

  • Difficult to maintain: Less documentation comment to describe usage*1, Less fresh document to describe (e.g. how to implement plugin), Too wide scope,
  • Slow performance: Not ready to use multi-thread so efficiently. No support for incremental analysis provided by build tools.
  • Difficult to test: To test Findbugs plugin, test-driven-detectors4findbugs was good solution but it doesn't work with Findbugs 3.0.1 due to internal implementation change. We also need a hack to test by Maven.

Yes Findbugs is OSS, so in theory we can solve them by own. But recently this project is not so active, and there is no popular fork for now. It would be problem to solve.

New alternative: error-prone

Last week I found an interesting static analysis tool, named error-prone.

This does not check bytecode, it applies hack to javac so it handles AST under com.sun.source.tree package. In my understanding, it has many good points:

  • Providing automated correction.
  • Providing simple but enough guideline, so we can write unit test to test rules to detect bug pattern.
  • It's product from Google so it has detailed documentation comment.
  • Using Annotation Processor to manage metadata of bug pattern, so we do not have to maintain XML files,

I haven't tried it with large amount of code, so I cannot compare its performance with Findbugs yet. I hope it's better than Findbugs. About openness and activeness in its community, I'm not sure yet. I've sent a pull-request to add bug pattern, I hope it's open even to non Google developers.

Do we need to switch to error-prone?

In my understanding, problem in error-prone is as follows:

So if you're using Findbugs, I think you do not have to switch to error-prone for now, its merit is really limited and almost all of them are not for users but for contributors.

But if you're author of Findbugs plugin, I think error-prone has value to keep watching on it. If its agility and resource is enough, it might grow and replace other solution later.

*1:I've sent some patches and pulll-requests but it's not enough yet


社内勉強会向けに作成したエラーログと例外の扱いについて説明したスライドを、Speakerdeckで公開しました。一部社内特化部分(ログレベルポリシーやMSA向けMDC使用法 など)を削除して、口頭で補足した部分を補っています。





上海Microsoftで行われたShanghai Docker MeetupのLTにて発表した、docker-composeを使って開発環境をContributorに対して配布するというユースケースに関するスライドをSpeaker Deckに公開しました。

Partake開発の際はVagrantで開発環境を配布していたのですが、今ならdocker-composeの方がシンプルかつ幅広く使われているのではと思います*1。中国からだとToolboxのダウンロードやDocker registryからのダウンロードが安定しないという問題があるのですが、中国Microsoftでミラー等の公開を検討しているそうです。





社内勉強会向けに作成したコード内コメントとJavadocの書き方についてのスライドを、Speaker DeckとSliDeckで公開しました。



プレゼン後に「publicでないクラスやメソッドJavadocを書くべきか?」という質問を受けましたが、私の答えは「書くべき」です。自分自身の理解を深め、備忘にもなり、将来のメンテナンスも助けてくれます。少しでも直感的でないコードがあるならば、時間を取って書きたいです。 まぁ書くべきものは厳密には対外的なAPI Specではなく、内部実装方針や歴史的経緯等になるかもしれませんので、Javadocを書くべきというよりは開発者向けドキュメントを書くべきと言うべきなのかもしれません。

また、ドキュメンテーションコメントはOSS contributionの良い題材になるとも話しました。typo修正くらいなら敷居は低いですし、多くのOSSでは喜ばれるはずです。自分の経験上、リジェクトされることはほとんどありませんでした:


エンジニアのためのJavadoc再入門講座 現場で使えるAPI仕様書の作り方

エンジニアのためのJavadoc再入門講座 現場で使えるAPI仕様書の作り方



  • etcd
    • KVS
    • Leader/Follower
    • Raft
  • fleet
    • Deploy
    • Service Discovery
  • Hashicorp Consul
    • CP
    • needs several nodes as server per Datacenter
    • each nodes in Datacenter installs Consul agent
  • Hashicorp Serf
    • AP
    • is used by Consul
  • Docker Compose
    • Define set of container instances
  • Docker Swarm
  • Docker Machine
    • Create and initialise instance to deploy Docker container
    • Supports both remote and local
  • Registrator
    • Hook for docker command, to register/unregister container instances
  • Netflix Eureka
    • Service Discovery
  • SkyDNS2
    • CP
    • DNS but not only address but also ports
    • Depends on etcd
  • Hashicorp Terraform
    • Deployment
  • Hashicorp Otto
  • Hashicorp Packer
  • Netflix Asgard
  • systemd
  • Sensu

Guava Release19がそろそろ来そう



// before
  public static final CharMatcher WHITESPACE =
      new NamedFastMatcher("WHITESPACE") {
// after
  public static CharMatcher whitespace() {
    return Whitespace.INSTANCE;

  static final class Whitespace extends NamedFastMatcher {
    static final Whitespace INSTANCE = new Whitespace();

なおこうした内部クラスを利用する方法*1はマルチスレッド環境でもsynchronizedや明示的なロックが必要ないことで知られています*2。 Stringでもprimitive型でもない定数、特に正規表現のような初期化処理が重いものは、積極的にファクトリメソッドで置き換えると良さそうです。

*1:このページのlazy initialization holder class idiom



今日、拙作findbugs-slf4jGitHub Pageを作りました。このブログではこのプロジェクトについて日本語で紹介したいと思います。


  • 拙作PMDプラグインをもとに、2012年8月から実装を開始したfindbugsプラグイン
  • SLF4J利用時のよくあるトラブルを未然に防ぎ、コードの品質を担保する
  • 全自動なので、開発者各々の個性に影響されずに品質の底上を実現できる


SLF4J(Simple Logging Facade for Java)はJava向けに開発された、ログ用のFacadeです。開発者はSLF4Jが提供するインタフェースを利用することで、「高パフォーマンスなログ処理」と「利用者に好きなログ基盤を選ばせる自由」を提供することができます。例えばLog4j 2のような新しいログ基盤でも、プログラムがSLF4Jを使っていれば、プログラムには手を加えること無く利用が可能です。

ただしSLF4Jのインタフェースはやや独特で、学習と慣れが必要です。例えば下記に挙げる例ではexample 1のほうが直感的ですが、SLF4Jではexample 2の方を推奨しています。この方法はパフォーマンス上有利なのですが、コードに長年手が加えられていくとプレースホルダとパラメータ数の不一致などが容易に発生するため、ログに残すべき値が残せていなかったなどのトラブルに繋がります。

// example 1: not good, because JVM will concat strings even if debug log is needless
logger.debug("User id is: " + userId);

// example 2: better, because it will not generate needless string if debug log is needless
logger.debug("User id is: {}", userId);

また例外のstacktraceを出力するためのメソッドinfo(String format, Object... arguments)だというのもわかりにくい点です。以下の例のように可変長配列の最後の要素がThrowableであればstacktraceを出力してくれるのですが、これはドキュメントを読むか人に聞くかしなければわからないでしょう。

// example 3: not good, because stacktrace and log messages are separated into two log records.
// And user cannot configure how to log stacktrace.
logger.warn("Exception ({}) occurred when userId is {}", e.getMessage(), userId);

// example 4: better, it's configurable and not separated into multiple log records.
logger.warn("Exception occurred when userId is {}", userId, e);



私が開発したfindbugsプラグインの発想はごくシンプルなもので、上記で挙げた問題を機械による検証によって解決するというものです。 個人の経験と尽力によって回避するのではなく、検証を機械化し自動化することでコストの削減とスケーラビリティの向上、抜け漏れ防止を実現します。



findbugsプロジェクトは息が長いということもあり、コードが非常に難解です。またテストも困難です。 このプラグイン開発では統合テストを重視テストパターンを増やすことで、TDDを可能にしつつエンバグを減らすことに努めています。またバグ修正時はまず再現テストを書く、ということを徹底しています。

またTravis CIが提供する機能により、Java 7&8SLF4J 1.6&1.7の2軸でビルドマトリックスを組んでいます。これも多くの環境をサポートする上で非常に役立っています。





以上です。 もし皆さんのプロジェクトでSLF4Jを使っていたら、ぜひ当findbugsプラグインの利用を検討してみてください。Mavenで使う方法はこちらに書いてあります