Search code examples
javamavenflyway

Why flyway's database driver dependency is not declared within the plugin itself in maven's pom.xml?


Most plugins relying on some other packages tend to declare the dependency in the plugin configuration. For example, spotbugs' doc does this

<plugin>
  <groupId>com.github.spotbugs</groupId>
  <artifactId>spotbugs-maven-plugin</artifactId>
  <version>4.2.0</version>
  <dependencies>
    <!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
    <dependency>
      <groupId>com.github.spotbugs</groupId>
      <artifactId>spotbugs</artifactId>
      <version>4.2.3</version>
    </dependency>
  </dependencies>
</plugin>

The version of spotbugs "core" is specified in plugin > dependencies > dependency.

However, flyway seems not working this way. For example, the following config where the database driver is in <dependencies> runs just fine.

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

    ...

    <build>
        <plugins>
            <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <version>${flyway.version}</version>
                <configuration>
                    <url>jdbc:mysql://localhost:3306/mydb</url>
                    <user>root</user>
                    <password>root</password>
                </configuration>
            </plugin>
        </plugins>
    </build>

Questions:

  1. Does this mean dependencies (at least compile and runtime scoped ones) are in the classpath of build-time goals as well?
  2. This might be subjective, but if there is indeed a best practice, it will obviously help beginners like me. So is it good/common coding style to write flyway's dependency in the "global" <dependencies> tag?

Solution

  • Taking mvn flyway:migrate as an example.

    The source mojo has requiresDependencyResolution = ResolutionScope.TEST configured in its annotation, which according to maven's doc, will enable access to pretty much all dependencies defined in <dependencies>.

    Then in AbstractFlywayMojo.java (which is a super class for MigrateMojo.java), compile and runtime classpath elements are added to classloader. It is later processed by org.flywaydb.core.internal.scanner.Scanner to load the necessary class.