Platform

Quarkus 扩展生态系统由社区(包括 Quarkus 核心开发团队)开发并维护的 Quarkus 扩展组成。尽管 Quarkus 生态系统(有时也称为“Quarkus 宇宙”)包含了所有开发的 Quarkus 扩展,但它也有一个 Quarkus 平台的概念。

The Quarkus extension ecosystem consists of the Quarkus extensions developed and maintained by the community, including the Quarkus core development team. While the Quarkus ecosystem (sometimes also referred to as the "Quarkus universe") includes all the Quarkus extensions ever developed, there is also a concept of a Quarkus platform.

Quarkus Platform

Quarkus 平台的基本承诺是该平台组成的任何 Quarkus 扩展组合均可在同一应用程序中使用,而不会彼此造成任何冲突。创建其 Quarkus 平台的每个组织可能会制定它们自己的标准,以将扩展纳入该平台以及保证已接受的扩展之间的兼容性的方法。

The fundamental promise of a Quarkus platform is any combination of the Quarkus extensions the platform consists of can be used in the same application without causing any conflict for each other. Each organization creating their Quarkus platform may establish their own criteria for the extensions to be accepted into the platform and the means to guarantee the compatibility between the accepted extensions.

Quarkus Platform Artifacts

每个 Quarkus 平台均定义为几个工件。

Each Quarkus platform is defined with a few artifacts.

Quarkus Platform BOM

每个 Quarkus 平台应提供 Maven BOM 工件,该工件

Each Quarkus Platform is expected to provide a Maven BOM artifact that

  • imports a chosen version of io.quarkus:quarkus-bom (the platform BOM may be flattened at the end, but it has to be based on some version of io.quarkus:quarkus-bom)

  • includes all the Quarkus extension artifacts (the runtime and the deployment ones) the platform consists of

  • includes all the necessary third-party artifacts that align the transitive dependency versions of the platform extensions to guarantee compatibility between them

  • includes the platform-descriptor artifact

  • possibly includes the platform-properties artifacts

要包含来自 Quarkus 平台的扩展的 Quarkus 应用程序将导入 Quarkus 平台 BOM。

Quarkus applications that want to include extensions from a Quarkus platform will be importing the Quarkus platform BOM.

Quarkus Platform Descriptor

Quarkus 平台描述符是一个 JSON 工件,可为 Quarkus 工具提供有关该平台及其扩展的信息。例如 [role="bare"][role="bare"]https://code.quarkus.io/ 和 Quarkus 命令行工具根据用户的请求参考此描述符来列示、添加和移除项目中的扩展。此工件还用作 Quarkus 平台标识符。当 Quarkus 工具需要识别项目中使用的 Quarkus 平台时,它们将分析该项目的依赖版本约束(根据 Maven 术语为 dependencyManagement 部分中托管依赖的有效列表),搜索它们中的平台描述符工件。鉴于平台描述符包含在 Quarkus 平台 BOM 中,因此每个 Quarkus 应用程序均会从导入的平台 BOM(作为依赖版本约束(Maven 中的托管依赖)继承平台描述符工件。

Quarkus platform descriptor is a JSON artifact that provides information about the platform and its extensions to the Quarkus tools. E.g. [role="bare"]https://code.quarkus.io/ and the Quarkus command line tools consult this descriptor to list, add and remove extensions to/from the project on user’s request. This artifact is also used as a Quarkus platform identifier. When Quarkus tools need to identify the Quarkus platform(s) used in the project, they will analyze the dependency version constraints of the project (the effective list of the managed dependencies from the dependencyManagement section in Maven terms) looking for the platform descriptor artifact(s) among them. Given that the platform descriptors are included into the Quarkus platform BOMs, every Quarkus application will inherit the platform descriptor artifact from the imported platform BOM(s) as a dependency version constraint (managed dependency in Maven terms).

为了能够在项目的依赖约束中轻松识别 Quarkus 平台描述符,平台描述符 Maven 工件坐标应遵循以下命名约定:

To be able to easily identify Quarkus platform descriptors among the project’s dependency constraints, the platform descriptor Maven artifact coordinates should follow the following naming convention:

  • the groupId of the descriptor artifact should match the groupId of the corresponding Quarkus Platform BOM;

  • the artifactId of the descriptor artifact should be the artifactId of the corresponding Quarkus Platform BOM with the -quarkus-platform-descriptor suffix;

  • the classifier of the descriptor artifact should match the version of the corresponding Quarkus Platform BOM;

  • the type of the descriptor artifact should be json;

  • the version of the descriptor artifact should match the version of the corresponding Quarkus Platform BOM.

它将作为字符串 <platform-bom-groupId>:<platform-bom-artifactId>-quarkus-platform-descriptor:<platform-version>:json:<platform-version> 出现

As a string it will look like <platform-bom-groupId>:<platform-bom-artifactId>-quarkus-platform-descriptor:<platform-version>:json:<platform-version>

例如,Quarkus BOM 的描述符的坐标 {quarkus-platform-groupid}:quarkus-bom::pom:1.2.3 将为 {quarkus-platform-groupid}:quarkus-bom-quarkus-platform-descriptor:1.2.3:json:1.2.3。而对于使用 BOM org.acme:acme-bom::pom:555 定义的自定义 Quarkus 平台,它将为 org.acme:acme-bom-quarkus-platform-descriptor:555:json:555.might

E.g. the coordinates of the descriptor for the Quarkus BOM {quarkus-platform-groupid}:quarkus-bom::pom:1.2.3 will be {quarkus-platform-groupid}:quarkus-bom-quarkus-platform-descriptor:1.2.3:json:1.2.3. And for a custom Quarkus platform defined with BOM org.acme:acme-bom::pom:555 it will be org.acme:acme-bom-quarkus-platform-descriptor:555:json:555.

匹配平台版本的分类器起初似乎很让人困惑。但这正是将描述符变成平台真正“指纹”的方式。在 Maven 和 Gradle 中,通过合并所有导入的 BOM 以及在当前项目中单独指定的版本约束(或管理的依赖项)以及它的父项来获取依赖项版本约束的有效集合(或管理的依赖项)。构件 classifier 是依赖项 ID 的一部分,可以表示为 groupId:artifactId:classifier:type。这意味着如果项目导入几个 BOM,例如 org.apple:apple-bom::pom:1.0org.orange:orange-bom::pom:1.0,并且这两个 BOM 中的每一个都导入一个不同的版本 {quarkus-platform-groupid}:quarkus-bom::pom,那么 Quarkus 工具将能够检测到这一事实,并告知用户,因为它 *might*不是一个安全的组合。如果描述符构件不包含包含平台版本的分类器,那么工具将无法检测到同一个项目中不同版本的同一个平台的潜在不兼容组合。

The classifier matching the version of the platform may look confusing at first. But this is what turns the descriptor into a true "fingerprint" of the platform. In both Maven and Gradle, the effective set of the dependency version constraints (or the managed dependencies) is obtained by merging all the imported BOMs and version constraints specified individually in the current project and also its parent(s). The artifact classifier is a part of the dependency ID, which could be expressed as groupId:artifactId:classifier:type. Which means that if a project imports a couple of BOMs, e.g. org.apple:apple-bom::pom:1.0 and org.orange:orange-bom::pom:1.0, and each of these two BOMs imports a different version {quarkus-platform-groupid}:quarkus-bom::pom, the Quarkus tools will be able to detect this fact and make the user aware of it, since it might not be a safe combination. If the descriptor artifact didn’t include the classifier containing the version of the platform then the tools wouldn’t be able to detect a potentially incompatible mix of different versions of the same platform in the same project.

平台描述符通常使用 Maven 插件生成,例如:

The platform descriptor will normally be generated using a Maven plugin, e.g.

<plugin>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-platform-descriptor-json-plugin</artifactId>
  <version>${quarkus.version}</version> 1
  <executions>
    <execution>
      <phase>process-resources</phase>
      <goals>
        <goal>generate-extensions-json</goal> 2
      </goals>
    </execution>
  </executions>
  <configuration>
    <bomGroupId>${quarkus.platform.group-id}</bomGroupId> 3
    <bomArtifactId>${quarkus.platform.artifact-id}</bomArtifactId> 4
    <bomVersion>${quarkus.platform.version}</bomVersion> 5
    <overridesFile>${overridesfile}</overridesFile> 6
    <resolveDependencyManagement>true</resolveDependencyManagement> 7
  </configuration>
</plugin>
1 the version of the quarkus-platform-descriptor-json-plugin
2 generate-extensions-json is the goal generating the platform descriptor
3 the groupId of the platform BOM
4 the artifactId of the platform BOM
5 the version of the platform BOM
6 this parameter is optional, it allows to override some metadata from the Quarkus extension descriptors found in every runtime extension artifact from which the platform descriptor is generated
7 this parameter is also optional and defaults to false. It has to be set to true in case the platform BOM is not generated and is not flattened. Which for example is the case for io.quarkus:quarkus-bom.

Quarkus Platform Properties

Quarkus 平台可以为某些配置选项提供其自己的默认值。

A Quarkus platform may provide its own default values for some configuration options.

Quarkus 正在使用 SmallRye Config 来配置应用程序配置。Quarkus 平台可以用作由应用程序的 application.properties 支配的配置源层次结构中的另一个配置源。

Quarkus is using SmallRye Config for wiring application configuration. A Quarkus platform may be used as another source of configuration in the hierarchy of the configuration sources dominated by the application’s application.properties.

为了提供特定于平台的默认值,该平台需要在其 BOM 中包含一个属性构件的依赖关系版本约束,其坐标遵循以下命名约定:

To provide platform-specific defaults, the platform needs to include a dependency version constraint in its BOM for a properties artifact whose coordinates follow the following naming convention:

  • the groupId of the properties artifact should match the groupId of the corresponding Quarkus Platform BOM;

  • the artifactId of the properties artifact should be the artifactId of the corresponding Quarkus Platform BOM with the -quarkus-platform-properties suffix;

  • the classifier of the descriptor artifact should be left empty/null;

  • the type of the descriptor artifact should be properties;

  • the version of the descriptor artifact should match the version of the corresponding Quarkus Platform BOM.

属性构件本身应为传统的 properties 文件,该文件将加载到 java.util.Properties 类的实例中。

The properties artifact itself is expected to be a traditional properties file that will be loaded into an instance of java.util.Properties class.

在这一点上,平台属性只能为受限制的一组配置选项提供默认值。平台属性文件中的属性名称必须以后缀 platform. 为前缀。

At this point, platform properties are only allowed to provide the default values for a restricted set of configuration options. The property names in the platform properties file must be prefixed with the platform. suffix.

希望让自己的配置选项特定于平台的扩展开发者应当将自己的默认值设置为以后缀 platform. 开头的属性。示例如下:

Extension developers that want to make their configuration options platform-specific should set their default values to properties that start with the platform. suffix. Here is an example:

package io.quarkus.deployment.pkg;

@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
@ConfigMapping(prefix = "quarkus")
public interface NativeConfig {

    /**
     * The docker image to use to do the image build
     */
    @WithDefault("${platform.quarkus.native.builder-image}")
    String builderImage();
}

在这种情况下,quarkus.native.builder-image 的默认值将由平台提供。当然,用户仍然可以将其 application.properties 中的 quarkus.native.builder-image 设置为所需的。但是,如果用户未自定义,则默认值将来自平台属性。示例的上方平台属性文件将包含:

In this case the default value for quarkus.native.builder-image will be provided by the platform. The user will still be able to set the desired value for quarkus.native.builder-image in its application.properties, of course. But in case it’s not customized by the user, the default value will be coming from the platform properties. A platform properties file for the example above would contain:

platform.quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:{mandrel-flavor}

还有一个 Maven 插件目标,用于验证平台属性内容及工件坐标,同时检查平台属性工件是否存在于平台的 BOM 中。这是一个示例插件配置:

There is also a Maven plugin goal that validates the platform properties content and its artifact coordinates and also checks whether the platform properties artifact is present in the platform’s BOM. Here is a sample plugin configuration:

<plugin>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-platform-descriptor-json-plugin</artifactId>
  <version>${quarkus.version}</version>
  <executions>
    <execution>
      <phase>process-resources</phase>
      <goals>
        <goal>platform-properties</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Merging Quarkus Platform Properties

如果应用程序导入多个 Quarkus 平台,并且这些平台包含各自的平台属性工件,那么这些平台属性工件的内容将合并,形成一组属性,用于应用程序构建。属性工件合并的顺序将对应于它们在应用程序依赖版本约束列表中出现的顺序(以 Maven 术语而言,这将对应于应用程序管理依赖的有效列表,即扁平化的 managedDependencies POM 部分)。

In case an application is importing more than one Quarkus platform and those platforms include their own platform properties artifacts, the content of those platform properties artifacts will be merged to form a single set of properties that will be used for the application build. The order in which the properties artifacts are merged will correspond to the order in which they appear in the list of dependency version constraints of the application (in the Maven terms that will correspond to the effective list of application’s managed dependencies, i.e. the flattened managedDependencies POM section).

先前找到的属性工件的内容将高于应用程序依赖约束中之后找到的内容!

The content of the properties artifacts found earlier will dominate over those found later among the application’s dependency constraints!

这意味着,如果某个平台需要覆盖其基于平台中定义的某个属性值,它需要在其 BOM 的 managedDependencies 部分中包含其平台属性工件,然后再导入基础平台。

That means if a platform needs to override a certain property value defined in the platform it is based on, it will need to include its platform properties artifact into the managedDependencies section of its BOM before importing the base platform.

例如,我们假设 org.acme:acme-quarkus-bom 平台通过导入其 BOM 来扩展 io.quarkus:quarkus-bom 平台。如果 org.acme:acme-quarkus-bom 平台将覆盖包含在 io.quarkus:quarkus-bom 中的 io.quarkus:quarkus-bom-quarkus-platform-properties 中定义的某个属性,那么 org.acme:acme-quarkus-bom 需要这样构成

For example, let’s assume org.acme:acme-quarkus-bom platform extends the io.quarkus:quarkus-bom platform by importing its BOM. In case, the org.acme:acme-quarkus-bom platform were to override certain properties defined in the io.quarkus:quarkus-bom-quarkus-platform-properties included in the io.quarkus:quarkus-bom, the org.acme:acme-quarkus-bom would have to be composed as

  <!-- skipped content -->

  <artifactId>acme-quarkus-bom</artifactId>
  <name>Acme - Quarkus - BOM</name>
  <packaging>pom</packaging>

  <dependencyManagement>
    <dependencies>
      <!-- Acme Quarkus platform properties -->
      <dependency>
        <groupId>org.acme</groupId>
        <artifactId>acme-quarkus-bom-quarkus-platform-properties</artifactId>
        <type>properties</type>
        <version>${project.version}</version>
      </dependency>

      <!-- The base Quarkus BOM -->
      <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>${quarkus.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

  <!-- skipped content -->

这样,org.acme:acme-quarkus-bom 平台属性将出现在 io.quarkus:quarkus-bom 属性提供的属性之前,从而在构建时优先使用。

That way, the org.acme:acme-quarkus-bom platform properties will appear before those provided by the io.quarkus:quarkus-bom properties and so will be dominating at build time.