Kengo's blog

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

2019年初頭でのMaven Site作成における注意点

最近新しいMaven Plugin用サイトを作ったので、mvn siteで作成できるサイトについて現時点での注意点をまとめる。

skinについて

maven-fluido-skinが最も使われていてかつ実用的と思われる。以下の記述はこのskinのv1.7を利用することを前提とする。

maven-site-pluginの設定方法

Maven3から<reportPlugins>による設定が可能になっているが、最新の公式サイトでは非推奨になっているので利用を避ける。

This new configuration format is not actually ready for end-users: please don't use it for the moment.

Copyright情報の生成

ページのフッターにCopyright情報が記載されるが、これはpom.xml<organization><inceptionYear>から情報を得て生成される。データが得られないとCopyright Holderが空になり違和感があるので、記入しておくと良い。

Markdownの利用

maven-site-plugindoxia-module-markdownに対する依存を追加すれば良い。.mdファイルはsrc/site/markdown以下に置く。

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
          <dependencies>
            <dependency>
              <groupId>org.apache.maven.doxia</groupId>
              <artifactId>doxia-module-markdown</artifactId>
              <version>1.8</version>
            </dependency>
          </dependencies>
        </plugin>

Maven Plugin用サイトの生成

Requirement 情報の生成

plugin-info.htmlMavenJDK 1.8、MemoryそしてDisk SpaceのRequirementを明記することができる。これはmaven-plugin-pluginの機能で、<requirements>を利用して設定できる。他にも特殊なRequirementがあるなら<others>を使って明記することもできるようだ。

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-plugin-plugin</artifactId>
        <configuration>
          <requirements>
            <maven>${maven.version}</maven>
            <jdk>1.8</jdk>
          </requirements>
        </configuration>
      </plugin>

HelpMojoの作成

昔から変わらないのでコピペで良い。

2018年のOSS活動状況まとめ

GitHubによると、今年は合計950 Contributions(25日時点)でした。仕事でほぼ使ってないのにこの数字というのは、多いのでしょうか少ないのでしょうか。

SpotBugs周りの開発

2018年もSpotBugsが一番活発な開発でした。新機能開発はほぼ無く純粋なバグ修正がほとんどですが、リリース周りも担っていたので100 commitsを超える貢献をしていました。

f:id:eller:20181225115534p:plain
contributors of spotbugs 2018

同organizationの他プロジェクトでもsonar-findbugs 48 commits, spotbugs-gradle-plugin 43 commits, spotbugs-archetype 17 commitsという感じで、Mavenプラグインを除けば最も活発なcontributorでした。

個人プロジェクト

個人プロジェクトではrtd-bot 72 commits, errorprone-slf4j 46 commits, findbugs-slf4j 44 commits, gradle-helper-for-java-8 40 commits, javadocky 39 commits, what-is-maven 13 commitsという感じでした。

rtd-botで使っているGitHub Probotはいろんな自動化が気軽にできそうで楽しいです。Sentryでサービスの監視をしていますが、Heroku上でChromeが起動しないことがあり、サービス自体はあまり安定させられていません。コストを掛けてサーバのスペックを上げないと解決でき無さそうなので、Read The Doc側のAPIが整備されるのを待つ形です。

今年でErrorproneプラグインもだいたい書けるようになり、これでPMD・Checkstyle・SpotBugs(FindBugs)・ErrorproneとJava周りの静的解析ツールはひととおりプラグインを実装できるようになりました。最近はJenkinsやMavenプラグインに加えGradleのプラグインも学習中なので、ビルド周りの自由度はだいぶ上がった気がします。

個人的に気になっているProject Reactorについては、Javadocky以外に使いみちを見いだせていないのが残念な感じです。流行りのサーバーレスと合わせるならSpring Cloud Functionのような使いみちになるのでしょうが、そもそもサーバーレスではSpring自体ほぼ使わないという……。GraalVMでの起動高速化が一般的になれば別でしょうが、それまではJavaを利用しないという選択肢も有力だと個人的には考えています。

来年の抱負

SpotBugs本体は旧バージョンのメンテナンスを止めて新機能開発に注力できる予定なので、以前からやりたいと話しているマルチスレッド対応を盛り込めればと思っています。1年でできるとは正直思ってませんが、とりあえず依存関係を整理してスレッドアンセーフなクラスを特定することはできるでしょう。おそらくBCELに依存するほぼすべてのDetectorがダメだとは思いますが……。

加えるなら、TypeScript・Kotlin・Rustといった言語の開拓でしょうか。基礎はもうあると思いますし、簡単なツールなら実装済みなのですが、もう少し複雑な事例も経験しておきたいところです。

Read The Docs利用者用にPRレビュー支援Probotを作りました

私がSpotBugsなどで使っているドキュメントホスティングサービス、Read The Docsを使う上で助けになるGitHub Probotを作成しました。

github.com

ドキュメントがいつもどおり全部英語なので、日本語での解説をここに書いておきます。

想定ユーザ

  • Read The Docsを使ったドキュメント作成を複数人で行っている
  • Read The Docsの設定をあまりいじっていない

解決する問題

  • Read The Docsが単体でPRレビュー用ビルドを提供していないので、レビューしてもらう時にステージングサイトやスクリーンショットを主導で用意しなければならない。

解決手法

  • PR作成時に docs ディレクトリに変更が入っていれば、Read The Docs上でのビルドとホスティングを有効化し、アクセス用URLをPRに書き込む。

インストール方法

  1. Read The DocsプロジェクトをGitHubリポジトリと接続しておく、あるいはGitHub Webhookと統合しておく
  2. Read The Docsプロジェクトに rtd-bot ユーザをメンテナーとして招待しておく。
  3. Gitリポジトリ.github/config.ymlrtd.project を作成し、Read The Docsプロジェクト名とその言語を指定する
  4. GitHub上でrtd-botを有効化する

注意点

  • いまのところ、Read The Docs側の設定項目(例えばドキュメントの場所など)には柔軟に追従できません。
  • 現バージョンのRead The Docsにおける「メンテナーの招待」は、「全権限の委譲」にほかなりません。不安な場合はご自身でProbotをホストいただけます。

技術的な工夫と、今後の開発の予定

このプロジェクトではCommitizenSemantic Releaseを導入しました。思っていたよりも使いやすく、またDependabotがすでにcommitizen風コミットコメントに対応していたため、特に導入に障害はありませんでした。MavenやGradleでも使えたら良いんですが、そこはまだハックが必要そうです。

Read The DocsのAPIはまだ機能不足が目立ちます。最近出たAPI v2でも認証機能すら無く、公開データへの読み取りアクセスしかできません。 今回はこの問題の回避にPuppeteerを使っています。つまり管理画面をNode.jsで操作しています。だいぶダーティハックですが、利用規約上も問題ないはずです。画面の更新には逐次追随する必要がありますが、過去の経験から言ってRead The Docsの画面はさほど大きく変更が入らないと思われます。

直近の予定としては、i18nには対応したいと考えています。他にも対応必要な設定があればROADMAP.mdに追記のPRを送ってください。

dockerでSonarQubeのインストールを楽にやる

クラスメソッドさんのブログでSonarQubeの紹介がされています。そちらの記事では記事の半分ほどを割いてインストール方法を説明していますが、dockerを使えばより楽に行えますのでその方法を紹介します。

dev.classmethod.jp

検証用のSonarQubeを立ち上げる

以下のコマンドで、組み込みデータベースを使用したサーバが立ち上がります。ユーザ名admin、パスワードadminでログインできます。 このコマンドは英文公式ページからの引用です。

$ docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube

なおalpineを使ったイメージもあるのですが、2018年8月1日現在でClassNotFoundErrorが出るなど不安定なようです。7.1-slpineなどのバージョンではなく、7.1などのバージョンの利用を推奨します。

PostgreSQLを使ったSonarQubeを立ち上げる

組み込みデータベースでの運用は検証用にのみ推奨されていますので、本番運用はRDBMSの利用が必要です。 以下のページにSonarQubeとPostgreSQLを立ち上げるdocker-compose.ymlが紹介されていますので、これを保存したディレクトリでdocker-compose upすればSonarQubeとPostgreSQLが立ち上がります。

docker-sonarqube/recipes.md at master · SonarSource/docker-sonarqube · GitHub

プラグインのインストールを自動化する

$SONARQUBE_HOME/extensions/pluginsディレクトリにプラグインの.jarファイルを保存することで、プラグインをインストールし有効化できます。 例えばSonarQube 6.7.4 LTSに sonar-findbugsとそれが依存しているSonarJavaをインストールするDockerfileは以下のようになります:

FROM sonarqube:7.1

RUN wget -P $SONARQUBE_HOME/extensions/plugins/ --no-verbose https://github.com/spotbugs/sonar-findbugs/releases/download/3.7.0/sonar-findbugs-plugin-3.7.0.jar && \
    wget -P $SONARQUBE_HOME/extensions/plugins/ --no-verbose https://sonarsource.bintray.com/Distribution/sonar-java-plugin/sonar-java-plugin-5.6.0.15032.jar

SpotBugsプラグインを元にしたSonarQubeプラグインを実装する方法

SpotBugsプラグインの実装方法には公式ドキュメントがありますが、SpotBugsプラグインをSonarQube上で実行するための手法はまだ固まっていません。最近Guava Migration HelperのSonarQubeプラグインのリリースに動いているので、要点をまとめておきます。

SonarQubeプラグイン実装の基本

まずSonarQubeの公式ドキュメントに目を通しておきます。特にMarketplaceでの公開を前提としている場合は、Plugin Keyの命名に制約があったり、SonarCloudの利用が必須だったりしますので、制約についてよく読んでおくと良いでしょう。

Mavenプロジェクトを作る

Gradleサポートは公式ではないので、Mavenを選択します。SpotBugsプラグインと同じプロジェクトで管理すると、メタデータ作成(後述)で手間がかからないのでおすすめです。私のプロダクトではSpotBugsプラグインとSonarQubeプラグインとをサブモジュールとして管理するプロジェクトを使っています。注意点は以下の通りです:

  • SonarQubeプラグイン<packaging>sonar-plugin</packaging>にする。
  • sonar-packaging-maven-pluginの設定に<basePlugin>findbugs</basePlugin><requirePlugins>findbugs:3.5</requirePlugins>を入れる。sonar-findbugs v3.5は初めてSpotBugsを導入したバージョンなのでこれ以降のバージョンを指定するのが良い。
  • SpotBugsプラグインが何らかのライブラリに依存している場合、普通のパッケージとshadedパッケージと両方を用意すると良い。 shadedはAntユーザやCLIユーザなど推移的依存が自動的に解決されない場合(プラグイン手配置が必要な場合)に便利。 shadedだけ用意すると、推移的依存が自動的に解決される場合に同じライブラリを複数回ダウンロードするリスクや、dependencyReducedPomによって依存先のメタデータが隠匿されてしまう(例えばライセンス管理がやりにくくなる)問題も生じる。

rule.xmlを生成する

SonarQubeはfindbugs.xmlやmessages.xmlを読まないので、SonarQubeが読める形式でルールに関するデータを提供する必要があります。私はこれをMavenプラグインで自動生成しています。ルールによってタグを変える必要がある大型プロジェクトじゃない限り、これで十分だと思います。

コードを書く

基本的にはPlugin.javaとRulesDefinision.javaの2つで足ります。以下がサンプル:

注意点は以下の通りです:

  • Context#createRepository()の第一引数は"findbugs"である必要がある。 それ以外の値だと、sonar-findbugsが検知してくれない その結果 findbugs-include.xml にBugが登録されないので、SpotBugsプラグインが解析に使われても結果一覧に出てこなくなる。

リリースする

あとはいつもどおりMaven Centralに公開した上で、SonarSourceコミュニティのフォーラムで申請すれば通るようです。私のプラグインはまだ申請中です:

JJUG CCC 2018 SpringでSpotBugs3.1系実装について話してきました

先週末に開催されたJJUG CCC 2018 Springに参加してきました。昨年に引き続き、SpotBugsに関する内容です。

20名ちょっとのエンジニアに参加いただき、3.1系実装で苦労しているところ、Java9対応が進まない理由などを話しました。Togetterはこちら

Maven Central Statisticsからもわかっていたことですが、まだFindBugsユーザのほうが多いですね。Java8移行を使っているならSpotBugsの方が安定&高速なので、ぜひ移行を検討いただきたいです。よくできていると好評のマイグレーションガイドもあります。

聴講したものの中では、アンカンファレンスが面白かったです。初めて参加したのですが、様々な立場の方がご自身の経験と考えをもとに意見を交換するのは参加していて楽しく感じます。こういう議論をもっと日頃からできると良いですね。また自分は参加しませんでしたが、海外登壇経験者のパネルディスカッションも面白かったようです。自分は海外在住なのにあまり参加経験がないので、そのうち行ってみたいところ。