VSCode 拡張 Apex PMDでWITH USER_MODEなどApexの新しい機能を利用する方法
こんにちは遠藤です。
VSCode上でPMDを実行しリアルタイムに静的解析の結果を教えてくれる拡張「Apex PMD」は非常に便利な拡張でみなさんもすでにお使いかと思います。
しかし、この「Apex PMD」、今はメンテナンスが止まってしまっておりApexの新しめの機能であるWITH USER_MODEなどには未対応な状況です。
この記事では、まずVSCodeの「Apex PMD」と拡張から利用されるPMD自体がApexの新しい機能にどの程度対応しているのかを確認します。その後、「Apex PMD」で可能な限り新しいバージョンのPMDに置き換えてApexの新機能に対応させる方法について解説していきます。
各ツールのApex新機能への対応状況
PMDの対応状況
まず、Apex PMDから利用されるPMD自体の対応状況を確認していきます。
ユーザモードデータベース操作による Apex コードの保護 (正式リリース)
SOQLは「WITH USER_MODE」、DML操作は「as user」を付与するとユーザモードでデータベース操作が実行されるというSpring '23で正式リリースされた機能です。
PMDのリリースを追ってみたところ、6.53でSOQLのWITH USER_MODEには対応してました。しかし、DML操作の「as user」構文には最新版でも未対応です。
PMDは抽象構文木(AST)の構築にApexパーサー「apex.jorje」を利用していますが、PMDに含まれているjorjeのバージョンは「as user」構文に対応していません。
実際「as user」を付与してApexコードに対してPMDを実行すると構文エラーとなってしまいます。
net.sourceforge.pmd.lang.a.ParseException:
apex.jorje.services.exception.ParseException:
Syntax(error = UnexpectedToken(loc = (12, 11, 80,
82), token = 'as'))
現在、apex.jorjeをUpdateするIssueとPRがオープンされており。こちらで「as user」への対応もされているようです。
一方で、もともとはapex.jorjeのメンテナンスが停止されていたため、apex.jorjeの使用をやめ、PMDプロジェクト内で独自にApex用パーサーの実装を進めていたようです。
Openされている関連するPRは以下がありますが、まだmasterへのPRはありません。
こちらは数ヶ月更新が無いので、独自のApexパーサーを実装している間に、jorjeに更新があり優先度が変わってしまったのかもしれません。
jorjeはオープンソースではないため、リリースを追えませんがSalesforce Extension Packの以下のPRに「Valid syntax like insert, as user, as system and Assert class is shown correctly with no error.」とあるので対応済みと考えて良さそうです。
いずれにしても、「as user」への対応が早くリリースされることを期待したいところです。
こちらは、Winter '23でリリースされたAssertクラスのことです。
Apexテストのアサーションに、Assertクラスを使用すると「ApexUnitTestClassShouldHaveAsserts」エラーが出てしまうことが悩みのタネでした。
Assertクラスについては、6.49で対応済みです。
VSCode拡張Apex PMDの対応状況
PMDの対応状況を踏まえてVSCode 拡張の「Apex PMD」について確認します。
冒頭で触れた通りApex PMDは開発者が個人なこともありメンテナンスに難がある状況です。現在の最新のバージョンは0.5.9ですが、このバージョンに含まれるPMDは6.42とだいぶ古く、SOQLのWITH USER_MODEにもAssertクラスにも対応していません。
vscode-pmd-apexリポジトリでは、6.53版にバージョンアップするPRがだいぶ前からOpenされていますが、マージされる気配はありません。
Apex PMDは、プロジェクトが古くnode.jsのv18以降ではビルドができなくなっています。そのあたりもなかなか開発が進まない原因なのかもしれません。
Apex PMDのPMDを新しいバージョン6.55に置き換えるには
では、本題の新しいバージョンのPMDをApex PMDで利用する手順について解説します。
VSCode拡張のマーケットプレイスからインストール可能なPMD Apexのバージョンでも、拡張設定でPMDのjarファイルを含むディレクトリを指定することで、同梱されている6.42よりも新しいバージョンを指定して動かすことができます。
PMD 6.xの最新は6.55で、こちらにはSOQLのUSER_MODEやAssertクラスの対応などが含まれています。
現在RCの7.xは、PMDコマンドの実行パラメータが変更されるため、指定可能なのは6.x系のみになります。
設定は、拡張機能の設定の「Apex PMD: Pmd Bin Path」にパスを指定します。
以下の手順で設定します。
1) https://pmd.github.io/ を開きスクロールして「6.55.0 (25-February-2023)」の「Download」をクリックしてバイナリーをダウンロードします。
2) ダウンロードされたzipファイル「pmd-bin-6.55.0.zip」を適当な場所に展開します。
3) Apex PMDの設定を開き、「ユーザー」または「ワークスペース」のタブを選択します。
4) 展開したディレクトリのlibを「Apex PMD: Pmd Bin Path」に指定します。以下は、ユーザディレクトリの下に配置した場合の例です。
実際に、SOQLにWITH USER_MODEを追加してみましたが、エラーが解消しました。
注意点としては「as user」を使用するとPMDコマンドの実行自体がエラーとなり、VSCode拡張のApex PMDは「0 issues」と判定してしまいます。一見エラーが解消したように見えてしまうので注意が必要です。
「as user」が修正されたPMDをビルドして検証してみた
「as user」への対応については、PR「 [apex] Update jorje #4605」がオープンされていると前述しましたが。こちらのPR元のリポジトリのブランチ「https://github.com/adangel/pmd/tree/issue-3973-apex-jorje」をビルドして修正を確認してみました。
また、ビルドのターゲットバージョンは7.x系なので、VSCodeプラグインの「PMD Apex」も7.x系のコマンドパラメータに対応したものを作成して試しています。
この記事では、結果のみの報告としますが、以下のように「as user」を使用した15行目ではApexCRUDViolationエラーが消えています。
また、他の行のエラーは残っているためコマンドが正常に動作していることが確認できました。
おわりに
以上、PMD Apexで使用するPMDバージョンを6.55に置き換えることで、WITH USER_MODEとAssertクラスへの対応、その他Apex用の更新を利用することができました。
また、「as user」への対応については、PR「 [apex] Update jorje #4605」がマージされた際には解消することがわかりました。このPRが早くマージされることを期待したいところです。
今回は、記事で紹介していませんが、「Apex PMD」が引き続きメンテナンスがされない状況であれば、PMDの7.x系で「as user」への対応がリリースされたあたりで、7.x系に対応した「Apex PMD」の作り方を公開したいと思います。