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
.