Conditional Extension Dependencies

Quarkus extension dependencies are usually configured in the same way as any other project dependencies in the project’s build file, e.g. the Maven pom.xml or the Gradle build scripts. However, there are dependency types that aren’t yet supported out-of-the-box by Maven and Gradle. What we refer here to as "conditional dependencies" is one example.

Conditional Dependencies

The idea behind the notion of the conditional dependency is that such a dependency must be activated only if a certain condition is satisfied. If the condition is not satisfied then the dependency must not be activated. In that regard, conditional dependencies can be categorized as optional, i.e. they may or may not appear in the resulting set of project dependencies.

In which cases could conditional dependencies be useful? A typical example would be a component that should be activated only in case all of its required dependencies are available. If one or more of the component’s required dependencies aren’t available, instead of failing, the component should simply not be activated.

Quarkus Conditional Extension Dependencies

Quarkus supports conditional extension dependencies. I.e. one Quarkus extension may declare one or more conditional dependencies on other Quarkus extensions. Conditional dependencies on and from non-extension artifacts aren’t supported.

Let’s take the following scenario as an example: quarkus-extension-a has an optional dependency on quarkus-extension-b which should be included in a Quarkus application only if quarkus-extension-c is found among its dependencies (direct or transitive). In other words, the presence of quarkus-extension-c is the condition which, if satisfied, enables quarkus-extension-b during the build of a Quarkus application.

The condition which triggers activation of an extension is configured in the extension’s descriptor, which is included into the runtime artifact of the extension as META-INF/quarkus-extension.properties. Given that extension descriptor is generated by the Quarkus plugin at extension build time, extension developers can add the following configuration to express the condition which would have to be satisfied for the extension to be activated:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-b</artifactId> (1)

  <!-- SKIPPED CONTENT -->

  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-extension-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <phase>process-resources</phase>
            <goals>
              <goal>extension-descriptor</goal> (2)
            </goals>
            <configuration>
              <dependencyCondition> (3)
                <artifact>org.acme:quarkus-extension-c</artifact> (4)
              </dependencyCondition>
            </configuration>
          </execution>
        </executions>
      </plugin>

  <!-- SKIPPED CONTENT -->
1 runtime Quarkus extension artifact ID, in our example quarkus-extension-b;
2 the goal that generates the extension descriptor which every Quarkus runtime extension project should be configured with;
3 configuration of the condition which will have to be satisfied for this extension to be included into a Quarkus application expressed as a list of artifacts that must be present among the application dependencies;
4 an artifact key (in the format of groupId:artifactId[:<classifier>:<extension>] but typically simply <groupId>:<artifactId>) of the artifact that must be present among the application dependencies for the condition to be satisfied.
In the example above the artifact used in the condition configuration happens to be a runtime Quarkus extension artifact but it could as well be any other artifact. There could also be more than one artifact element in the body of dependencyCondition.

Now, having a dependency activating condition in the descriptor of quarkus-extension-b, other extensions may declare a conditional dependency on it.

A conditional dependency is configured in the runtime artifact of a Quarkus extension. In our example, it’s the quarkus-extension-a that has a conditional dependency on quarkus-extension-b, which can be expressed in two ways.

Declaring a dependency as optional

If an extension was configured with a dependency condition in its descriptor, other extensions may configure a conditional dependency on it by simply adding <optional>true</optional> to the dependency configuration. In our example it would look like this:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-a</artifactId> (1)

  <!-- SKIPPED CONTENT -->

  <dependencies>
    <dependency>
      <groupId>org.acme</groupId>
      <artifactId>quarkus-extension-b</artifactId> (2)
      <optional>true</optional>
    </dependency>

  <!-- SKIPPED CONTENT -->
1 the runtime extension artifact quarkus-extension-a
2 declares an optional Maven dependency on the runtime extension artifact quarkus-extension-b
In general, for every runtime extension artifact dependency on another runtime extension artifact there must be a corresponding deployment extension artifact dependency on the other deployment extension artifact. And if the runtime dependency is declared as optional then the corresponding deployment dependency must also be configured as optional.
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-a-deployment</artifactId> (1)

  <!-- SKIPPED CONTENT -->

  <dependencies>
    <dependency>
      <groupId>org.acme</groupId>
      <artifactId>quarkus-extension-b-deployment</artifactId> (2)
      <optional>true</optional>
    </dependency>

  <!-- SKIPPED CONTENT -->
1 the deployment extension artifact quarkus-extension-a-deployment
2 declares an optional Maven dependency on the deployment extension artifact quarkus-extension-b-deployment

Normally, optional Maven extension dependencies are ignored by the Quarkus dependency resolver at build time. In this case though, the optional dependency quarkus-extension-b includes a dependency condition in its extension descriptor, which turns this optional Maven dependency into a Quarkus conditional extension dependency.

If quarkus-extension-b wasn’t declared as <optional>true</optional> that would make quarkus-extension-b a required dependency of quarkus-extension-a and its dependency condition would be ignored.

Declaring a conditional dependency in the Quarkus extension descriptor

Conditional dependencies can also be configured in the Quarkus extension descriptor. The conditional dependency configured above could be expressed in the extension descriptor of quarkus-extension-a as:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  <!-- SKIPPED CONTENT -->

  <artifactId>quarkus-extension-a</artifactId> (1)

  <!-- SKIPPED CONTENT -->

  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-extension-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <phase>process-resources</phase>
            <goals>
              <goal>extension-descriptor</goal> (2)
            </goals>
            <configuration>
              <conditionalDependencies> (3)
                <extension>org.acme:quarkus-extension-b:${b.version}</extension> (4)
              </conditionalDependencies>
            </configuration>
          </execution>
        </executions>
      </plugin>

  <!-- SKIPPED CONTENT -->
1 runtime Quarkus extension artifact ID, in our example quarkus-extension-a
2 the goal that generates the extension descriptor which every Quarkus runtime extension project should be configured with
3 conditional dependency configuration element
4 artifact coordinates of conditional dependencies on other extensions.

In this case, the Maven dependency is not at all required in the pom.xml.

Related content