MavenのactiveByDefaultにはクセがある
Mavenで複数のプロファイルを切替える場合に、そのデフォルトとして、プロファイルをマークするのがactiveByDefault
という設定なわけですが、これの挙動が少し想像とズレていたのでそのメモ。
サンプルは以下。
https://github.com/yo1000/example.Maven-ActiveByDefaults
要件
- Java 1.8.0_121
- Maven 3.5.3
$ ./mvnw -v
Apache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-25T04:49:05+09:00)
Maven home: ~/.m2/wrapper/dists/apache-maven-3.5.3-bin/2c22a6s60afpuloj4v181qvild/apache-maven-3.5.3
Java version: 1.8.0_121, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.13.3", arch: "x86_64", family: "mac"
検証
検証に際し、以下のようなpom.xml
を用意しました。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yo1000</groupId>
<artifactId>example.maven.activeByDefault</artifactId>
<version>1.0.0</version>
<name>example.maven.activeByDefault</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>A</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>B</id>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>C</id>
</profile>
</profiles>
</project>
検証内容
依存関係の設定が異なる、プロファイルなし
と、3つのプロファイルを用意しました。まとめると以下の4つです。
- プロファイル
なし
:kotlin-stdlib-1.0.0
に依存 - プロファイル
A
:kotlin-stdlib-1.1.0
に依存(activeByDefault
) - プロファイル
B
:kotlin-stdlib-1.2.0
に依存 - プロファイル
C
: 個別の依存設定はないため、プロファイルなし
と同義
これらに対し、以下のコマンドを発行したときに、依存関係にどのような変化があるかを検証します。
./mvnw clean dependency:tree -P ${ProfileId}
検証結果
以下5パターンの検証をしました。それぞれ結果です。
プロファイルなし
kotlin-stdlib:jar:1.1.0
に依存。activeByDefault
の設定が効いているため、プロファイルA
が適用される結果となった。
./mvnw clean dependency:tree
[INFO] com.yo1000:example.maven.activeByDefault:jar:1.0.0
[INFO] \- org.jetbrains.kotlin:kotlin-stdlib:jar:1.1.0:compile[INFO] \- org.jetbrains:annotations:jar:13.0:compile
プロファイルA
kotlin-stdlib:jar:1.1.0
に依存。プロファイルA
を指定したため、プロファイルA
が適用される結果となった。
./mvnw clean dependency:tree -P A
[INFO] com.yo1000:example.maven.activeByDefault:jar:1.0.0
[INFO] \- org.jetbrains.kotlin:kotlin-stdlib:jar:1.1.0:compile[INFO] \- org.jetbrains:annotations:jar:13.0:compile
プロファイルB
kotlin-stdlib:jar:1.1.0
に依存。プロファイルB
を指定したため、プロファイルB
が適用される結果となった。
./mvnw clean dependency:tree -P B
[INFO] com.yo1000:example.maven.activeByDefault:jar:1.0.0
[INFO] \- org.jetbrains.kotlin:kotlin-stdlib:jar:1.2.0:compile[INFO] \- org.jetbrains:annotations:jar:13.0:compile
プロファイルC
kotlin-stdlib:jar:1.0.0
に依存。プロファイルC
を指定したため、プロファイル側での依存はない状態が適用される結果となった。
./mvnw clean dependency:tree -P C
[INFO] com.yo1000:example.maven.activeByDefault:jar:1.0.0
[INFO] \- org.jetbrains.kotlin:kotlin-stdlib:jar:1.0.0:compile[INFO] \- org.jetbrains.kotlin:kotlin-runtime:jar:1.0.0:compile
プロファイルX
kotlin-stdlib:jar:1.1.0
に依存。activeByDefault
の設定が効いているため、プロファイルA
が適用される結果となった。
./mvnw clean dependency:tree -P X
[INFO] com.yo1000:example.maven.activeByDefault:jar:1.0.0
[INFO] \- org.jetbrains.kotlin:kotlin-stdlib:jar:1.1.0:compile[INFO] \- org.jetbrains:annotations:jar:13.0:compile
実はこのパターンこそが、今回のポストを書く発端となったものでした。pom.xml
に定義されていないプロファイルが指定された場合、どうなるのか。
当初想像していたのは、プロファイルが存在しないため、プロファイル側での依存はない状態(kotlin-stdlib:jar:1.0.0
に依存)が適用されるものかと思い込んでいました。
ところが、実際の結果では想像と異なり、存在しないプロファイルが指定された場合、プロファイルが指定されなかった場合と同じように扱われてしまい、activeByDefault
の設定されたプロファイル(kotlin-stdlib:jar:1.1.0
に依存)が適用されました。
つまり、activeByDefault
というのはpom.xml
に定義されていないプロファイルが指定された場合にも、効いてしまうようなのです。
以上のような結果が得られたため、activeByDefault
を使用する場合には、適用されるプロファイルに注意したい。