できない.dev

Maven「Unknown lifecycle phase」の原因と直し方

Unknown lifecycle phase は、引用符の中の語を正しいフェーズ名に直せば消える。
PowerShell で .test.skip=true のような語が出たら、-D の引数を引用符で囲む。

公開:

要約

mvn に渡した語のうち、フェーズとしてもプラグインのゴールとしても解釈できないものがあると、ビルドが始まる前に止まる。
Maven 3.10.0 で mvn clean-install を実行すると次の行が出る(後半のフェーズの一覧は途中を省いた)。

[ERROR] Unknown lifecycle phase "clean-install". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: pre-clean, clean, post-clean, validate, ... site-deploy. -> [Help 1]

Unknown lifecycle phase の後ろの引用符の中が、Maven がフェーズとして受け取った語だ。
まずここを見る。clean-install のような打ち間違いならすぐ分かるが、".test.skip=true" のように自分では打ったつもりのない断片が出ていたら、シェルが引数を分けている。

解決策

1. 引用符の中の語を正しいフェーズ名に直す

使えるフェーズはエラーの Available lifecycle phases are: の後ろに並んでいる。
よく使うのは clean・compile・test・package・verify・install だ(Introduction to the Build Lifecycle(新しいタブで開く))。

mvn clean install

2. PowerShell では -D の引数を引用符で囲む

引数全体を引用符で囲むと、1 つの引数として渡る。

mvn clean install "-Dmaven.test.skip=true"

ほかに、先頭にバッククォートを置いて `-Dmaven.test.skip=true と書く方法(PowerShell のエスケープ)と、--%(stop-parsing token)を置く方法がある。--% はそれ以降の行をそのまま渡すので、同じ行に ; で別のコマンドをつなぐと、それも引数になってしまう(about_Parsing(新しいタブで開く))。

mvn --% clean install -Dmaven.test.skip=true

ドットを含む別のプロパティでも同じことが起きる。
Windows PowerShell 5.1 で -Dspring-boot.run.profiles=dev を引用符なしで渡すと、-Dspring-boot と .run.profiles=dev に分かれた。

3. -D は空白を入れずに書く

mvn -DskipTests=true package

4. プラグインのゴールはコロンでつなぐ

プラグインのゴールは プレフィックス:ゴール の形で 1 語にする。LifecyclePhaseNotFoundException(新しいタブで開く) では、mvn compiler:compile や、プラグインの groupId と artifactId まで書く形が挙げられている。
Spring Boot のプラグインを使うプロジェクトなら、次のように書く。

mvn spring-boot:run

よくある原因

  1. フェーズ名を打ち間違えている。complie のような綴りの誤りや、clean と install をハイフンでつないだ clean-install がこれに当たる。
    複数のフェーズは空白で区切って並べる。
  2. PowerShell が -D の引数を分けている。
    Windows PowerShell 5.1 と PowerShell 7.4 で確かめたところ、-Dmaven.test.skip=true を引用符なしで書くと、ドットの手前で -Dmaven と .test.skip=true の 2 つに分かれて渡された。
    Maven 3.10.0 にこの 2 つを渡すと、.test.skip=true がフェーズとして扱われ、Unknown lifecycle phase ".test.skip=true" になる。
    ドットを含まない -DskipTests は分かれなかった。
  3. = の前後に空白がある。-DskipTests = true と書くと、= と true が別の引数になる。
    Maven 3.10.0 では Unknown lifecycle phase "=" が出た。
  4. ゴールの書き方が違う。mvn spring-boot run は spring-boot と run の 2 つのフェーズとして扱われ、Unknown lifecycle phase "spring-boot" になる。