Maven「No goals have been specified for this build」の原因と直し方
No goals have been specified for this build は、フェーズを付けて実行すれば直る。
mvn だけで動かしたいなら、pom.xml の defaultGoal に既定のフェーズを書いておく。
公開:
要約
mvn とだけ打つと、ビルドが始まる前に止まる。
Maven 3.10.0 では次の行が出る(後半のフェーズの一覧は途中を省いた)。
[ERROR] No goals have been specified for this build. 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, initialize, ... deploy, pre-site, site, post-site, site-deploy. -> [Help 1]No goals have been specified for this build は、何を実行するかが 1 つも指定されていないという意味だ。
Maven は mvn というコマンド名だけでは動かない。compile・package・install のようなライフサイクルのフェーズか、compiler:compile のようなプラグインのゴールを受け取って、初めてビルドを始める。
Maven 3.10.0 では、pom.xml の無いディレクトリで mvn とだけ打っても、there is no POM in this directory ではなくこのエラーが先に出た。
何を実行するかの確認が、POM を探すより前に行われるためだ。
解決策
1. フェーズを付けて実行する
やりたいことに合わせてフェーズを付ける。
フェーズを指定すると、そこまでの前段も順に実行される。
たとえば package なら、compile と test を済ませてから JAR を作る(Introduction to the Build Lifecycle(新しいタブで開く))。
mvn compile # コンパイルまで
mvn test # テストまで
mvn package # JAR などの成果物を作るまで
mvn clean install # 前回の成果物を消し、ローカルリポジトリに入れるまでオプションは、フェーズと一緒に書く。
mvn -DskipTests packageプラグインのゴールを直接呼ぶときは、プレフィックス:ゴール の形で書く。NoGoalSpecifiedException(新しいタブで開く) の例では mvn compiler:compile である。
2. スクリプトでは変数が空のときに備える
ゴールを変数で渡すなら、空のときの既定値を決めておく。
GOALS="${GOALS:-package}" # 空なら package
mvn $GOALSCI の設定でジョブごとに値を変えている場合は、そのジョブで値が渡っているかをログで確かめる。
3. 引数なしの mvn で動かしたいなら defaultGoal を書く
毎回同じフェーズを打つなら、pom.xml の <build> に <defaultGoal> を書いておく。POM Reference(新しいタブで開く) では、引数で何も指定されなかったときに実行するフェーズかゴールとされている。
<build>
<defaultGoal>package</defaultGoal>
</build>Maven 3.10.0 で <defaultGoal>validate</defaultGoal> を書いた pom.xml を置いたところ、mvn だけで BUILD SUCCESS になった。
ただし、チームの他の人や CI が mvn とだけ打ったときにも同じフェーズが走る。
ログを読んだときに何を実行したかが分かるよう、スクリプトや CI では mvn package のように明示しておく方がよい。
よくある原因
mvnだけを打っている。
コマンド名だけで既定のビルドが走ると思って実行している。- オプションだけを付けている。
-DskipTestsや-qは実行の仕方を変えるだけで、何を実行するかは決めない。
Maven 3.10.0 でmvn -DskipTestsを実行しても、同じエラーになった。 - ゴールを入れた変数が空になっている。
シェルスクリプトや CI でmvn $GOALSのように組み立てていて、変数に何も入っていない。
展開した後はmvnだけと同じになる。