© 2021 The original authors.

1. Introduction

WildFly Galleon Plugins project includes Galleon plugin and Maven plugin implementations that are dedicated to building feature-packs (including generation of feature specs, packages and other resources) for WildFly releases and provisioning of WildFly-based distributions. These plugins can also be used by projects that integrate into or extend WildFly.

1.1. Maven plugins

This Maven tooling allows to build feature-packs that can be combined with WildFly feature-packs to produce customized WildFly server installations.

The Maven plugin "org.wildfly.galleon-plugins:wildfly-galleon-maven-plugin" exposes 2 goals:

  • build-feature-pack: A goal to be used by WildFly developers when defining WildFly feature-packs that implement new WidFly subsystems and expose new server capabilities.

  • build-user-feature-pack: A goal to be used by WildFly server users in order to define new Layers, new JBoss Modules, …​ that depend on existing WildFly subsystems and capabilities.

1.2. Galleon plugins

During provisioning, a WildFly specific Galleon plugin is executed to install the WildFly server. This plugin can be configured with a set of options in order to tune the WildFly server installation. The way to provide these options is tool specific.

  • For the Galleon CLI command line tool: the options are exposed using completion (TAB key) for the install command. Options can also be set in the provisioning.xml file when using the provision command. A provisioning.xml file example:

<installation xmlns="urn:jboss:galleon:provisioning:3.0">
    <feature-pack location="wildfly@maven(org.jboss.universe:community-universe):current"/>
    <options>
        <option name="jboss-fork-embedded" value="false"/>
        <option name="jboss-maven-dist"/>
    </options>
</installation>
  • For the Galleon Maven plugin configuration: The <plugin-options> element contains the options as XML elements. For example:

<configuration>
...
 <plugin-options>
  <jboss-fork-embedded>true</jboss-fork-embedded>
 </plugin-options>
...
</configuration>
  • For the WildFly Maven plugin configuration: The <galleon-options> element contains the options as XML elements. For example:

<configuration>
...
 <galleon-options>
  <jboss-fork-embedded>true</jboss-fork-embedded>
 </galleon-options>
...
</configuration>
<configuration>
...
 <plugin-options>
  <jboss-fork-embedded>true</jboss-fork-embedded>
 </plugin-options>
...
</configuration>
  • For the prospero tool, you can define a provisioning.xml file that contains the options. A provisioning.xml file example:

<installation xmlns="urn:jboss:galleon:provisioning:3.0">
    <feature-pack location="wildfly@maven(org.jboss.universe:community-universe):current"/>
    <options>
        <option name="jboss-fork-embedded" value="false"/>
        <option name="jboss-maven-dist"/>
    </options>
</installation>

1.2.1. Installation Plugin options

Option

Type

Default value

Description

jboss-bulk-resolve-artifacts

Boolean

true

Maven artifacts that are needed for the WildFly server installation are resolved in a bulk operation instead of being resolved individually. That speed-up the provisioning time. By default 5 threads are used to resolve the artifacts. Use -Dmaven.artifact.threads=<number of threads> to increase concurrency. Using 500+ threads has shown excellent results.

jboss-cyclonedx

Boolean

true

Enable generation of a CycloneDX SBOM (Software Bill of Materials) for the provisioned distribution. The SBOM lists all resolved artifacts as CycloneDX components with Maven coordinates, Package URLs, and evidence recording each artifact’s location within the distribution. Enabled by default; set to false to skip SBOM generation.

jboss-cyclonedx-format

String (json or xml)

json

The output format for the generated CycloneDX SBOM. Only used when jboss-cyclonedx or jboss-cyclonedx-only is set to true.

jboss-cyclonedx-licenses

String (licenses.xml, pom, or off)

off

Controls how component license information is collected when SBOM generation is enabled. off (the default) disables license collection. licenses.xml reads the docs/licenses/*-licenses.xml summaries shipped by the feature-packs; it requires no remote artifact resolution and works in jboss-cyclonedx-only mode. pom instead resolves declared licenses from Maven POMs (walking parent POMs), which performs remote resolution. Additionally, true maps to licenses.xml and false maps to off.

jboss-cyclonedx-only

Boolean

false

Generate a CycloneDX SBOM without provisioning the server. Implies jboss-cyclonedx=true. When enabled, the plugin walks all included packages to discover artifact references from module templates, CopyArtifact tasks, and shaded model dependencies, and writes the SBOM. No file copying or configuration generation is performed, and no artifacts are installed. When channel-based resolution is in effect, artifact versions are resolved from the channel so the SBOM records the versions that would actually be provisioned; otherwise versions come from the feature-pack version properties. The jboss-cyclonedx-format and jboss-cyclonedx-output options still apply. Because the SBOM is the sole output in this mode, a generation failure always aborts, regardless of jboss-cyclonedx-fail-on-error.

jboss-cyclonedx-output

String

sbom.cdx.json (or sbom.cdx.xml) in the installation root

A path to the file where the generated CycloneDX SBOM will be written. Only used when jboss-cyclonedx or jboss-cyclonedx-only is set to true.

jboss-cyclonedx-pretty-print

Boolean

false

Pretty-print (indent) the generated SBOM for human readability. When false, the SBOM is written in a compact form. Only used when jboss-cyclonedx or jboss-cyclonedx-only is set to true.

jboss-cyclonedx-schema-version

String (e.g. 1.6, 1.7)

1.7

The CycloneDX schema version to use when serializing the SBOM. Only used when jboss-cyclonedx or jboss-cyclonedx-only is set to true.

jboss-cyclonedx-compress

Boolean

true

Compress the generated CycloneDX SBOM into a .gz archive. The gzip file will be named by appending .gz to the chosen output file name (e.g. sbom.cdx.json.gz), and the uncompressed SBOM file will not be kept. Enabled by default; set to false to keep the uncompressed SBOM. Only used when jboss-cyclonedx or jboss-cyclonedx-only is set to true.

jboss-cyclonedx-product-cpe

String (CPE 2.3)

NONE

Overrides the CPE of the SBOM’s main component. Normally the CPE is read from the distribution’s product manifest; set this only in the exceptional case where that CPE is wrong and must be corrected, or where the distribution carries none. Only used when jboss-cyclonedx or jboss-cyclonedx-only is set to true.

jboss-cyclonedx-fail-on-error

Boolean

false

Controls what happens when SBOM generation fails during a regular provisioning run. By default (false) the failure is logged as a warning and provisioning completes without a complete SBOM, so a problem generating the SBOM never prevents a server from being provisioned. Set to true to make such a failure abort provisioning instead. This option has no effect in jboss-cyclonedx-only mode, where the SBOM is the sole output and failures always abort.

jboss-dump-config-scripts

String

NONE

A path to a directory in which WildFly CLI script files used to generate the server configurations are stored.

jboss-fork-embedded

Boolean

false

Fork in a separate process the generation of the server configuration files. Server configuration generation implies the usage of a WildFly Embedded server. It is advised to set this env variable to true, specially when having multiple executions of the provisioning inside the same process (e.g.: multiple executions of Galleon|WildFly|Bootable JAR Maven plugins).

jboss-maven-dist

Boolean

false

Provision a thin WildFly server installation with JBoss Modules modules jar resolved from Maven local cache and not copied to the modules directory.

jboss-maven-repo

String

NONE

A path to a directory in which all the resolved Maven artifacts jars and associated pom files are stored. The generated directory complies with the filesystem layout of a Maven repository. This respository can then be used as the local cache of a thin WildFly server (see jboss-maven-dist option).

jboss-overridden-artifacts

'|' separated list of maven coordinates in the following syntax: GroupId:ArtifactId:Version:[Classifier:]Extension

NONE

A list of Maven artifact coordinates used to override the artifact versions that are defined in the provisioned WildFly feature-pack. For example, to override undertow-core: io.undertow:undertow-core:2.3.1.Final::jar

jboss-reset-embedded-system-properties

Comma-separated list of String

NONE

When executing a forked process to generate the server configuration, all system properties defined in the parent process are inherited by the forked process. Setting this property to an empty value will reset the system properties used by WildFly server during startup. To reset WildFly specific system properties and some additional properties, add to the comma-separated list the names of system property to reset. To not reset a WildFly specific system property, add the property name prefixed with - to the list.

jboss-resolved-artifacts-cache

String

NONE

A path to a directory where to cache the resolved Maven artifacts that are not part of the server installation (feature-packs, Galleon plugins, …​). NOTE: This option is specific to the usage of the prospero provisioning tool.

1.2.2. CycloneDX SBOM Generation

The WildFly Galleon plugin can generate a CycloneDX Software Bill of Materials (SBOM) for the provisioned distribution. The SBOM lists all resolved artifacts as CycloneDX components with Maven coordinates, Package URLs (purl), declared licenses, and — during a full provision — evidence recording where each artifact resides in the distribution.

Options at a glance
Option Purpose

jboss-cyclonedx

Enable SBOM generation during provisioning (enabled by default; set to false to disable).

jboss-cyclonedx-only

Generate the SBOM without provisioning the server (implies jboss-cyclonedx=true).

jboss-cyclonedx-fail-on-error

Whether an SBOM generation failure aborts provisioning (default false; always fatal in -only mode).

jboss-cyclonedx-format

Output format: json (default) or xml.

jboss-cyclonedx-output

Path to write the SBOM to.

jboss-cyclonedx-licenses

License source: off (default), licenses.xml, or pom.

jboss-cyclonedx-pretty-print

Indent the SBOM for readability.

jboss-cyclonedx-schema-version

CycloneDX schema version, defaults to 1.7.

jboss-cyclonedx-compress

Compress the generated SBOM into a .gz archive (appends .gz to the output file name).

jboss-cyclonedx-product-cpe

Override the main component CPE (exceptional cases only; see below).

See the options table above for full descriptions, types, and defaults.

Generation modes
  • During provisioning: SBOM generation is enabled by default; it runs alongside the server installation. The SBOM includes occurrences evidence recording each artifact’s file location(s) within the distribution. Set jboss-cyclonedx=false to disable it.

  • SBOM-only (no provisioning): Set jboss-cyclonedx-only=true to generate the SBOM without building the server. This mode is significantly faster as it skips file copying and configuration generation and installs no artifacts. Because no files are installed, the SBOM does not include file-location evidence. When channel-based resolution is in effect, artifact versions are still resolved from the channel so the recorded versions match what a full provision would install.

Failure handling

By default, a failure while generating the SBOM during a regular provisioning run is logged as a warning and provisioning completes without a complete SBOM — an SBOM problem never blocks a server from being provisioned. Set jboss-cyclonedx-fail-on-error=true to make such a failure abort provisioning instead. In jboss-cyclonedx-only mode the SBOM is the only output, so a generation failure always aborts regardless of this option.

Main component (the distribution)

The SBOM’s main component (metadata.component) represents the provisioned WildFly or JBoss EAP distribution itself, derived from the distribution’s own product branding. WildFly/EAP feature-packs contribute a product-conf artifact (artifactId ending -product-conf) whose manifest carries the release information; the plugin reads it in both provisioning and SBOM-only modes. The main component is populated as follows:

  • name / version from JBoss-Product-Release-Name / JBoss-Product-Release-Version (for example JBoss EAP / 8.1 Update 7.1, or WildFly / 40.0.0.Final).

  • purl / bom-ref a synthetic pkg:generic identity built from the name and version (for example pkg:generic/jboss-eap@8.1-update-7.1) — a distribution is not itself a Maven artifact.

  • publisher from Implementation-Vendor.

  • cpe from the manifest’s JBoss-Product-CPE entry, when present. This can be overridden with the jboss-cyclonedx-product-cpe option for the exceptional case where the manifest CPE is wrong, or supplied where the distribution carries none.

If no product-conf artifact is present — for example JBoss EAP 7, which ships the product identity as a plain module rather than a Maven artifact — the plugin falls back, best effort, to the provisioned product module manifest at modules/system/layers/base/org/jboss/as/product/<slot>/dir/META-INF/MANIFEST.MF, reading the same JBoss-Product-Release-Name / -Version entries. Because this reads an installed file, it applies only to a full provision; in SBOM-only mode (no files installed) EAP 7 yields no product branding. That manifest carries only name and version, so use jboss-cyclonedx-product-cpe to add a CPE.

If neither source provides branding, the main component falls back to a generic wildfly identity.

Where the product configuration comes from

The branding is not a hand-configured value; it is read from the same product-conf artifact the running server uses to report its identity. The chain is:

  1. A WildFly/EAP distribution selects a product slot in bin/product.conf (typically slot=main).

  2. The corresponding org.jboss.as.product/<slot> JBoss Modules module supplies the product identity. Its module.xml does not embed the identity directly; instead it references a Maven artifact, for example:

    <module name="org.jboss.as.product">
        <resources>
            <resource-root path="."/>
            <artifact name="${org.jboss.eap:wildfly-ee-feature-pack-product-conf}"/>
        </resources>
    </module>
  3. That referenced artifact — whose artifactId ends in -product-conf — carries the branding in its META-INF/MANIFEST.MF (JBoss-Product-Release-Name, -Version, Implementation-Vendor, and optionally JBoss-Product-CPE).

Because the product-conf artifact is a normal module dependency, it is recorded during provisioning and in SBOM-only mode (where no files are installed but module templates are still walked). The plugin therefore derives the main component by scanning the recorded artifacts rather than the installed filesystem — which is why it works identically in both modes.

Selection logic. Among the recorded artifacts, the plugin picks the one whose artifactId ends with -product-conf and that is a plain JAR with no classifier, then reads its manifest. This deliberately excludes the sibling version-marker artifact of the same name that some feature-packs publish with a version classifier and txt type. In a distribution there is exactly one such JAR:

  • EAP: org.jboss.eap:wildfly-ee-feature-pack-product-conf → JBoss EAP / 8.1 Update 7.1.

  • Community WildFly: org.wildfly:wildfly-feature-pack-product-conf (or the -ee- variant) → WildFly / the release version.

If the manifest lacks JBoss-Product-Release-Name or -Version, or no matching artifact is present, the plugin falls back to the provisioned product module manifest described under Main component above; failing that — or in SBOM-only mode, where that file is not installed — the generic wildfly fallback is used.

License information

Component licenses are collected according to jboss-cyclonedx-licenses:

  • licenses.xml (default): reads the docs/licenses/*-licenses.xml summaries that WildFly/EAP feature-packs ship. This requires no remote artifact resolution and is available in SBOM-only mode (the summaries are read from feature-pack package content). It is the recommended source: coverage and accuracy match or exceed the POM path for WildFly/EAP distributions.

  • pom: resolves declared licenses from each artifact’s Maven POM, walking parent POMs until a <licenses> block is found. This performs remote artifact resolution.

  • off: disables license collection.

Declared license names/URLs from either source are mapped to SPDX identifiers by the shared SPDX mapper before being written to the SBOM. Additionally, true maps to licenses.xml and false maps to off.

Component identity and evidence

Each resolved artifact is recorded as a component with its Maven group/name/version, a pkg:maven purl (including classifier/type qualifiers where applicable), and a SHA-256 hash. In a full provision, an evidence.occurrences list records every path at which the artifact appears in the distribution; the same artifact installed in multiple locations yields multiple occurrences.

Embedded SBOM merging

If a resolved JAR contains its own CycloneDX SBOM (a .cdx.json or .cdx.xml file, as produced by some upstream libraries), that SBOM is merged into the output under the JAR’s component, preserving the upstream component graph.

Shaded (uber) JAR detection

Artifacts assembled on the fly from multiple dependencies (shaded models) are recorded as a component with a pkg:generic identity and their constituent dependencies nested underneath. A dependency that appears only inside a shaded JAR is not emitted as a separate top-level component. Dependencies bundled inside a resolved JAR are likewise detected and attributed to that JAR.

Bundled JavaScript library detection

Artifacts with a resources classifier (such as the HAL Management Console hal-console) may contain bundled JavaScript libraries that are not visible as Maven dependencies. When SBOM generation is enabled, the plugin automatically detects these libraries by parsing JavaScript source map files (.js.map) inside the resource JAR.

Detected npm packages appear as nested components under the parent Maven artifact in the SBOM, with pkg:npm Package URLs. Version information is extracted on a best-effort basis from the embedded source content (version assignments, banner comments). If a version cannot be determined, the component is still recorded without a version.

This detection works in both provisioning and SBOM-only modes. In SBOM-only mode, the resource JAR is resolved from the Maven repository to enable source map scanning.

Examples

Galleon provisioning.xml:

<installation xmlns="urn:jboss:galleon:provisioning:3.0">
    <feature-pack location="wildfly@maven(org.jboss.universe:community-universe):current"/>
    <options>
        <option name="jboss-cyclonedx-only" value="true"/>
        <option name="jboss-cyclonedx-format" value="json"/>
    </options>
</installation>

WildFly Maven plugin:

<configuration>
...
 <galleon-options>
  <jboss-cyclonedx>true</jboss-cyclonedx>
  <jboss-cyclonedx-format>json</jboss-cyclonedx-format>
  <jboss-cyclonedx-licenses>licenses.xml</jboss-cyclonedx-licenses>
  <jboss-cyclonedx-pretty-print>true</jboss-cyclonedx-pretty-print>
 </galleon-options>
...
</configuration>

2. Building a custom feature-pack example

Defining your own Galleon feature-packs allow you to create customized WildFly server installation containing your custom content and trimmed to your need. In this example we are seeing how to setup a Maven project to create a Galleon feature-pack that contains Galleon layers to install static web content, a JDBC driver and a datasource.

2.1. Setting up Maven project

Call the following command to create an empty Maven project:

mvn archetype:generate -DarchetypeGroupId=org.codehaus.mojo.archetypes \
-DarchetypeArtifactId=pom-root -DgroupId=org.example.demo \
-DartifactId=my-custom-galleon-pack -DinteractiveMode=false

N.B.: The type of packaging of your pom.xml project file must be <packaging>pom</packaging>.

Add the Maven plugin dependency in your pom.xml file :

<dependencies>
  <dependency>
    <groupId>org.wildfly.galleon-plugins</groupId>
    <artifactId>wildfly-galleon-maven-plugin</artifactId>
    <version>8.2.2.Final</version>
  </dependency>
</dependencies>

Integrate the plugin in your build element:

 <build>
   <plugins>
     <plugin>
       <groupId>org.wildfly.galleon-plugins</groupId>
       <artifactId>wildfly-galleon-maven-plugin</artifactId>
       <executions>
         <execution>
           <id>myproject-galleon-pack-build</id>
           <goals>
             <goal>build-user-feature-pack</goal>
           </goals>
           <phase>compile</phase>
         </execution>
       </executions>
     </plugin>
   </plugins>
 </build>

2.2. Expressing a dependency on WildFly

A feature-pack has a dependency on WildFly feature-pack, this dependency is resolved from the project pom file. Add the WildFly Galleon feature-pack dependency to the project dependencies section:

<dependency>
  <groupId>org.wildfly</groupId>
  <artifactId>wildfly-galleon-pack</artifactId>
  <version>26.0.0.Final</version>
  <type>zip</type>
</dependency>

Expressing a dependency on WildFly 26.0.0.Final doesn’t mean that the feature-pack is limited to be used in conjunction with WildFly 26.0.0.Final. When provisioning your feature-pack with a WildFly feature-pack, the version of the WildFly feature-pack present in the provisioning will get used. This means that your feature-pack is usable with future WildFly release (WildFly guarantee backward compatibility there).

2.3. Source structure

Create the directory src/main/resources, it will contain the content of your feature-pack. The resources directory can contain the following sub-directories:

  • configs: contains default configurations provided by this feature-pack.

  • feature_groups: contains feature groups, a reusable unit that contains the server configuration content that can then be referenced from layers and configurations.

  • layers: contains layers, a layer reflects the content and configuration of a WildFly server capability that are provisioned when the layer is used.

  • modules: contains JBoss Modules modules you want to see packaged in the feature-pack. JBoss Modules modules can then be referenced from layers and configurations.

  • packages: contains packages, a package contains content you want to see installed in the server (eg: properties files, keystores, tools, scripts,…​).

In this example we are adding feature_groups, layers, modules and packages to our custom WildFly feature-pack.

2.4. Defining JBoss Modules modules

JBoss Modules modules can be referenced from Galleon layers and/or feature-groups using the module name. e.g.: org.mariadb.jdbc.

Under the modules directory create a directory path identical to the one we would find under the JBOSS_HOME/modules directory.

For this example create the directory src/main/resources/modules/org/mariadb/jdbc/main that will contain the module.xml file. NB: The actual JAR files that implement the module are NOT packaged inside the feature-pack, the JAR files are retrieved from Maven at provisioning time.

The module.xml file content is:

<?xml version="1.0" encoding="UTF-8"?>
<module name="org.mariadb.jdbc" xmlns="urn:jboss:module:1.8">
   <resources>
       <!-- Expression to retrieve the mariadb driver artifact from Maven. The version must be expressed in the feature-pack pom.xml dependencies-->
       <artifact name="${org.mariadb.jdbc:mariadb-java-client}"/>
   </resources>
   <!-- The JDBC driver depends on the following API -->
   <dependencies>
       <module name="javax.api"/>
       <module name="javax.transaction.api"/>
   </dependencies>
</module>

The pom.xml of your feature-pack project must also contain the actual dependency on the org.mariadb.jdbc:mariadb-java-client Maven artifact.

Add the following dependency to the project dependencies:

<dependency>
  <groupId>org.mariadb.jdbc</groupId>
  <artifactId>mariadb-java-client</artifactId>
  <version>2.7.2</version>
</dependency>

We are done defining the org.mariadb.jdbc JBoss Modules module. This module will get installed when the Galleon layer that references it is used. We will see that later when provisioning the custom feature-pack.

2.5. Defining packages

For each package you are defining, under the directory src/main/resources/packages/ create a directory with the name of the package. The usual package directory structure is:

packages/<package_name>
|- content/
|- pm/
|  `- wildfly/
|     `- tasks.xml
`- package.xml

The file package.xml is required, it contains the package name. Optionally it can contain the dependencies on other packages that would get installed when this package is provisioned.

XML syntax for the package.xml is covered by this XML schema.

Create the directory src/main/resources/packages/my-web-server-content.

The file src/main/resources/packages/my-web-server-content/package.xml content is:

<?xml version="1.0" ?>
<package-spec xmlns="urn:jboss:galleon:package:2.0" name="my-web-server-content"/>

The content directory includes content that will be copied to the installation root directory when the package is installed.

Create the directory src/main/resources/packages/my-web-server-content/content/my-web-server-content. It will contain our static web content.

Create the file src/main/resources/packages/my-web-server-content/content/my-web-server-content/index.html:

<html>
<body>
<h1>Hello World</h1>
</body>
</html>

Create the file src/main/resources/packages/my-web-server-content/content/my-web-server-content/Error404.html:

<html>
<body>
<h1>Resource not found!</h1>
</body>
</html>

When the package my-web-server-content is provisioned (because referenced from a Galleon layer), the directory my-web-server-content will get installed in the server.

pm/wildfly/tasks.xml file is optional, it may include instructions to copy and/or delete files and directories, create directories, resolve and copy Maven artifacts to the installation directory, etc. These tasks are executed when the content of all the packages has been copied into the installation.

The tasks XML schema contains the definition of the tasks you can add to the tasks.xml file. This example of tasks.xml file contains the set of tasks one can use in a tasks.xml file.

In the context of this example we don’t need to define a tasks.xml file.

2.6. Defining layers

One powerful aspect of Galleon are layers. By provisioning layers you can create a trimmed WildFly server containing only the set of features (server configuration and JBoss Modules modules) required by your application.

WildFly comes with a set of Galleon layers that allows you to provision a trimmed server containing subsystems configured in a way that is nearly identical to the default configuration (as found in standalone*.xml configuration).

In order to fine tune the trimmed server configuration, WildFly CLI tool can be an approach. Running CLI scripts imply to execute the CLI tool on each provisioned server instance.

By defining your own Galleon layers, you can provision a server already fully configured without the need for extra CLI script execution.

XML syntax for layers is covered by this XML schema.

A layer allows you to package inside a single artifact (the layer) some server configuration item (eg: subsystem configuration) and content (eg: JBoss Modules modules).

A good example is the JDBC driver. When adding a JDBC driver to a wildfly installation we are generally updating the datasources subsystem and add a JBoss Module module.

Now for each layer you are defining, create a directory with the name of the layer. Each directory contains a single file named layer-spec.xml that contains the actual content of the layer.

2.6.1. my-undertow-handler layer example

This layer configures undertow subsystem to serve the static content, sets a 404 handler and references the my-web-server-content package.

Create the directory src/main/resources/layers/standalone/my-undertow-handler.

Create the file src/main/resources/layers/standalone/my-undertow-handler/layer-spec.xml with the following content:

<?xml version="1.0" ?>
<layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="my-undertow-handler">
  <!-- features are added to the server configuration -->
  <feature spec="subsystem.undertow.server">
    <param name="server" value="default-server" />
    <feature spec="subsystem.undertow.server.host">
       <param name="host" value="default-host" />
       <feature spec="subsystem.undertow.server.host.location">
         <param name="location" value="/web"/>
         <param name="handler" value="my-web-server-content"/>
       </feature>
       <feature spec="subsystem.undertow.server.host.filter-ref">
         <param name="filter-ref" value="404-handler"/>
         <param name="predicate" value="true"/>
       </feature>
    </feature>
  </feature>
  <feature spec="subsystem.undertow.configuration.handler.file">
    <param name="file" value="my-web-server-content"/>
    <param name="path" value="${jboss.home.dir}/my-web-server-content"/>
    <param name="directory-listing" value="true"/>
  </feature>
  <feature spec="subsystem.undertow.configuration.filter.error-page">
    <param name="error-page" value="404-handler"/>
    <param name="code" value="404"/>
    <param name="path" value="${jboss.home.dir}/my-web-server-content/Error404.html"/>
  </feature>

  <!-- Packages content is installed inside the server -->
  <packages>
    <package name="my-web-server-content"/>
  </packages>
</layer-spec>

You will notice that a layer contains feature. You can see features as server Management resources. The spec attribute can be derived from the resource path used in JBoss CLI commands. The following CLI operations would have the same effect than the features instantiated in this layer:

/subsystem=undertow/configuration=handler/file=my-web-server-content:add(path="${jboss.home.dir}/my-web-server-content", directory-listing=true)
/subsystem=undertow/configuration=filter/error-page=404-handler:add(path="${jboss.home.dir}/my-web-server-content/Error404.html", code=404)
/subsystem=undertow/server=default-server/host=default-host/location="/web":add(handler=my-web-server-content)
/subsystem=undertow/server=default-server/host=default-host/filter-ref=404-handler:add(predicate=true)

2.6.2. mariadb-driver layer example

This layer contains the configuration for a mariadb JDBC driver.

Create the directory src/main/resources/layers/standalone/mariadb-driver.

Create the file src/main/resources/layers/standalone/mariadb-driver/layer-spec.xml with the following content:

<?xml version="1.0" ?>
<layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="mariadb-driver">
  <!-- Add the driver to the datasources subsystem -->
  <feature spec="subsystem.datasources">
    <feature spec="subsystem.datasources.jdbc-driver">
      <param name="driver-name" value="mariadb"/>
      <param name="jdbc-driver" value="mariadb"/>
      <param name="driver-xa-datasource-class-name" value="org.mariadb.jdbc.MariaDbDataSource"/>
      <param name="driver-module-name" value="org.mariadb.jdbc"/>
    </feature>
  </feature>

  <!-- Will install the JBoss Modules org.mariadb.jdbc module. -->
  <packages>
    <package name="org.mariadb.jdbc"/>
  </packages>
</layer-spec>

The following CLI operations would have the same effect than the features instantiated in this layer:

/subsystem=datasources/jdbc-driver=mariadb:add(driver-name=mariadb, \
driver-module-name=org.mariadb.jdbc, \
driver-xa-datasource-class-name=org.mariadb.jdbc.MariaDbDataSource)

2.6.3. mariadb-datasource layer example

A layer that adds a MariaDBDS datasource that is bound to the mariadb driver. This layer adds the ability to configure the datasource (host, port, database, username, password) thanks to environment variables that can be be set at server run-time.

Create the directory src/main/resources/layers/standalone/mariadb-datasource.

Create the file src/main/resources/layers/standalone/mariadb-datasource/layer-spec.xml with the following content:

<?xml version="1.0" ?>
<layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="mariadb-datasource">

  <!-- express a dependency on the driver layer to have it automatically provisioned when mariadb-datasource is provisioned -->
  <dependencies>
    <layer name="mariadb-driver"/>
  </dependencies>

  <feature spec="subsystem.datasources.data-source">
    <param name="data-source" value="MariaDBDS"/>
    <param name="jndi-name" value="java:jboss/datasources/${env.MARIADB_DATASOURCE:MariaDBDS}"/>
    <param name="connection-url" value="jdbc:mariadb://${env.MARIADB_HOST:localhost}:${env.MARIADB_PORT:3306}/${env.MARIADB_DATABASE}"/>
    <param name="driver-name" value="mariadb"/>
    <param name="user-name" value="${env.MARIADB_USER}"/>
    <param name="password" value="${env.MARIADB_PASSWORD}"/>
  </feature>
</layer-spec>

The following CLI operations would have the same effect than what we have expressed in this layer:

/subsystem=datasources/data-source=MariaDBDS:add(jndi-name="java:jboss/datasources/${env.MARIADB_DATASOURCE:MariaDBDS}", \
connection-url="jdbc:mariadb://${env.MARIADB_HOST:localhost}:${env.MARIADB_PORT:3306}/${env.MARIADB_DATABASE}", \
driver-name=mariadb, user-name="${env.MARIADB_USER}", password="${env.MARIADB_PASSWORD}")

2.7. Defining feature groups

XML syntax for feature-groups is covered by this XML schema.

A feature-group is contained inside an xml file located inside the src/main/resources/feature_groups. The XML file name is the name of the feature-group.

A feature-group allows you to group feature instantiation inside a group that can then be referenced from other groups or layers.

We could have chosen to define the undertow handler in a feature group and reference it from the layer.

The content of the src/main/resources/feature_groups/my-undertow-handler-grp.xml feature-group would look like:

<?xml version="1.0" ?>

<feature-group-spec name="my-undertow-handler-grp" xmlns="urn:jboss:galleon:feature-group:1.0">
  <!-- features are added to the server configuration -->
  <feature spec="subsystem.undertow.server">
    <param name="server" value="default-server" />
    <feature spec="subsystem.undertow.server.host">
       <param name="host" value="default-host" />
       <feature spec="subsystem.undertow.server.host.location">
         <param name="location" value="/web"/>
         <param name="handler" value="my-web-server-content"/>
       </feature>
       <feature spec="subsystem.undertow.server.host.filter-ref">
         <param name="filter-ref" value="404-handler"/>
         <param name="predicate" value="true"/>
       </feature>
    </feature>
  </feature>
  <feature spec="subsystem.undertow.configuration.handler.file">
    <param name="file" value="my-web-server-content"/>
    <param name="path" value="${jboss.home.dir}/my-web-server-content"/>
    <param name="directory-listing" value="true"/>
  </feature>
  <feature spec="subsystem.undertow.configuration.filter.error-page">
    <param name="error-page" value="404-handler"/>
    <param name="code" value="404"/>
    <param name="path" value="${jboss.home.dir}/my-web-server-content/Error404.html"/>
  </feature>

  <!-- Packages content is installed inside the server -->
  <packages>
    <package name="my-web-server-content"/>
  </packages>
</feature-group-spec>

Then, from the my-undertow-handler layer, we could have referenced the feature-group instead of the features:

<?xml version="1.0" ?>

<layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="my-undertow-handler">
  <feature-group name="my-undertow-handler-grp"/>
</layer-spec>

2.8. Building your feature-pack

This is done by calling mvn clean install in the maven project. A zip artifact org.example.demo:my-custom-galleon-pack:1.0-SNAPSHOT is built and installed in the maven local cache. This feature-pack artifact is what will get used when provisioning a WildFly server.

2.9. Making your feature-pack available

For local development and testing, having the feature-pack installed in the Maven local cache is all what you need. In order to share your feature-pack, it has to be deployed in remote Maven repositories.

2.10. Provisioning your feature-pack

The same feature-pack can be used to provision a server using different tooling. Usage is not limited to bare-metal, feature-packs can be used to provision custom WildFly server on the cloud. Main tools to provision custom WildFly servers are:

2.10.1. WildFly Bootable JAR Maven plugin

We will not go into all the details of how to provision a Bootable JAR, the Bootable JAR documentation covers it in detail. We are here showing plugin configuration extract in which we are referencing our custom feature-pack and layers.

<plugin>
    <groupId>org.wildfly.plugins</groupId>
    <artifactId>wildfly-jar-maven-plugin</artifactId>
    <configuration>
        <feature-packs>
            <!-- the List of feature-packs to use during provisioning. Always provide WildFly feature-pack as the first one. -->
            <feature-pack>
                <groupId>org.wildfly</groupId>
                <artifactId>wildfly-galleon-pack</artifactId>
                <version>26.0.0.Final</version>
            </feature-pack>
            <!-- Our custom feature-pack -->
            <feature-pack>
                <groupId>org.example.demo</groupId>
                <artifactId>my-custom-galleon-pack</artifactId>
                <version>1.0-SNAPSHOT</version>
            </feature-pack>
        </feature-packs>
        <!-- Layers in use to provision the server -->
        <layers>
            <!-- WildFly layer that provides web + support for datasources -->
            <layer>datasources-web-server</layer>
            <!-- The custom layers we have defined -->
            <layer>mariadb-datasource</layer>
            <layer>my-undertow-handler</layer>
        </layers>
        ...

2.10.2. WildFly Maven plugin

The configuration of feature-packs and layers is identical to the one we have seen in the Bootable JAR chapter.

3. Maven plugin

This chapter is dedicated to the Maven plugin that can be used to build WildFly-based feature-packs. Maven coordinates of the Maven plugin artifact are

Maven plugin installing feature-packs and provisioning distributions is a part of Galleon project itself. Please, refer to Galleon documentation for more information.
<dependency>
    <groupId>org.wildfly.galleon-plugins</groupId>
    <artifactId>wildfly-galleon-maven-plugin</artifactId>
    <version>8.2.2.Final</version>
</dependency>

3.1. Goals overview

generate-all-artifacts-list

Generates a list of all the artifacts required to install the full version of a feature-pack.

[_build_user_feature_pack]

Creates feature-packs intended to be built on top WildFly feature-packs.

[_build_feature_pack]

Creates a feature-pack archive from the provided resources in the WildFly fashion (used for official WildFly feature-packs).

3.2. generate-all-artifacts-list

3.2.1. wildfly-galleon:generate-all-artifacts-list

Full name: org.wildfly.galleon-plugins:wildfly-galleon-maven-plugin:8.2.2.Final:generate-all-artifacts-list

3.2.2. Description

Aggregate all artifact lists (offliners) of a feature-pack dependencies. In addition adds to the list the feature-pack itself and universe artifacts. The resulting list is attached as an artifact to the current project. If output-licenses-file is set, a license file for the contained artifacts is generated.

3.2.3. Attributes

  • Requires a Maven project to be executed.

  • Requires dependency resolution of artifacts in scope: runtime.

  • Binds by default to the lifecycle phase: compile.

Table 1. Required Parameters

Name

Type

Since

Description

[fpArtifactId]

String

-

(no description)
Alias is: feature-pack-artifact-id.

[fpGroupId]

String

-

(no description)
Alias is: feature-pack-group-id.

Table 2. Optional Parameters

Name

Type

Since

Description

[excludedVersions]

String

-

(no description)
Alias is: excluded-licenses-versions.

[extraArtifacts]

List

-

(no description)
Alias is: extra-artifacts.

[fpVersion]

String

-

(no description)
Alias is: feature-pack-version.

[licensesFile]

String

-

(no description)
Alias is: output-licenses-file.

[offline]

boolean

-

(no description)
Default value is: false.
Alias is: offline.

3.2.4. Parameter Details

excludedVersions
(no description)

  • Type: java.lang.String

  • Required: No

  • Alias: excluded-licenses-versions

extraArtifacts
(no description)

  • Type: java.util.List

  • Required: No

  • Alias: extra-artifacts

fpArtifactId
(no description)

  • Type: java.lang.String

  • Required: Yes

  • Alias: feature-pack-artifact-id

fpGroupId
(no description)

  • Type: java.lang.String

  • Required: Yes

  • Alias: feature-pack-group-id

fpVersion
(no description)

  • Type: java.lang.String

  • Required: No

  • Alias: feature-pack-version

licensesFile
(no description)

  • Type: java.lang.String

  • Required: No

  • Alias: output-licenses-file

offline
(no description)

  • Type: boolean

  • Required: No

  • Default: false

  • Alias: offline

3.3. build-user-feature-pack

3.3.1. wildfly-galleon:build-user-feature-pack

Full name: org.wildfly.galleon-plugins:wildfly-galleon-maven-plugin:8.2.2.Final:build-user-feature-pack

3.3.2. Description

This Maven Mojo is intended to be used to build feature-packs that depend on one of the WildFly feature-packs. This Maven mojo creates a WildFly style feature-pack archive from the provided resources according to the feature-pack build configuration file and attaches it to the current Maven project as an artifact. If no feature-pack build configuration is provided, some defaults are applied. The content of the future feature-pack archive is first created in the directory called feature-pack-layout under the module’s build directory which is then ZIPped to create the feature-pack artifact.

3.3.3. Attributes

  • Requires a Maven project to be executed.

  • Requires dependency resolution of artifacts in scope: runtime.

  • Binds by default to the lifecycle phase: compile.

Table 3. Required Parameters

Name

Type

Since

Description

[generateCompleteModel]

Boolean

-

(no description)
Default value is: false.
Alias is: generate-complete-model.

[resourcesDir]

String

-

Represents the directory containing child directories packages, feature_groups, modules etc. Either an absolute path or a path relative to configDir.
Default value is: src/main/resources.
User property is: wildfly.user.feature.pack.resourcesDir.
Alias is: resources-dir.

Table 4. Optional Parameters

Name

Type

Since

Description

[addFeaturePacksAsRequiredManifests]

boolean

-

Add any feature-pack dependency as a required manifest in the manifest YAML definition. This parameter has no effect if "generate-channel-manifest" is false.
Default value is: true.
Alias is: add-feature-packs-as-required-manifests.

[buildName]

String

-

The directory for the built artifact.
Default value is: ${project.build.directory}.
User property is: wildfly.user.feature.pack.buildName.

[configDir]

File

-

The feature-pack build configuration file directory
Default value is: ${basedir}.
User property is: wildfly.user.feature.pack.configDir.
Alias is: config-dir.

[configFile]

String

-

The feature-pack build configuration file.
Default value is: wildfly-user-feature-pack-build.xml.
User property is: wildfly.user.feature.pack.configFile.
Alias is: config-file.

[configStabilityLevel]

String

-

The default stability level used at provisioning time to generate configuration. Can’t be used when stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: config-stability-level.

[copyright]

String

-

(no description)
User property is: wildfly.feature.pack.copyright.
Alias is: copyright.

[cpeResolutionMode]

CpeResolutionMode

-

If the WildFly product-conf artifact contains a CPE, the provisioned maven artifacts of other feature-packs present in the provisioning configuration are not added to the generated SBOM. In order to advertise that a feature-pack is in the scope of the WildFly CPE, set this parameter to SERVER_PRODUCT_CONF. If no CPE is defined, then the content of feature-packs are added to the generated SBOM whatever the value of this parameter.
Default value is: LOCAL.
User property is: wildfly.sbom.sbom-cpe-resolution-mode.
Alias is: sbom-cpe-resolution-mode.

[deployChannelManifest]

boolean

-

(no description)
Default value is: true.
User property is: wildfly.feature.pack.deploy-channel-manifest.
Alias is: deploy-channel-manifest.

[forbidLowerStatibilityLevelPackageReference]

boolean

-

Enforce that no package at a lower stability level than the minimum-stability-level is referenced from Galleon constructs.
Default value is: false.
Alias is: forbid-lower-stability-level-package-reference.

[fpLocation]

String

-

The FPL for the generated feature-pack.
Default value is: ${project.groupId}:${project.artifactId}:${project.version}.
Alias is: feature-pack-location.

[generateChannelManifest]

boolean

-

Generates a channel manifest YAML definition when the feature-pack is produced. Any dependency from the feature-pack is declared as a stream in the channel manifest.
Default value is: false.
User property is: wildfly.feature.pack.generate-channel-manifest.
Alias is: generate-channel-manifest.

[includeIncompleCoordsArtifactsInSbom]

Boolean

-

(no description)
Default value is: false.
User property is: wildfly.sbom.include-incomplete-coords-artifacts-in-sbom.
Alias is: include-incomplete-coords-artifacts-in-sbom.

[minimumStabilityLevel]

String

-

The minimum stability level of the WildFly processes used to generate feature specs and include packages. Set this if you need to generate feature specs for features with a lower stability level than the default level of the WildFly process being used for feature-spec generation. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: minimum-stability-level.

[packageStabilityLevel]

String

-

The default stability level used at provisioning time when installing packages/JBoss Modules modules. Can’t be used when stability-level is set. If both the config-stability-level and the package-stability-level options are set, the level of the package-stability-level option must imply the level of the config-stability-level option. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: package-stability-level.

[releaseName]

String

-

The name of the release the feature-pack represents which will be stored in the feature-pack’s resources/wildfly/wildfly-tasks.properties as product.release.name property.
Default value is: ${product.release.name}.
Alias is: release-name.

[skipDoc]

boolean

-

(no description)
Default value is: false.
User property is: wildfly.feature.pack.skip-doc.
Alias is: skip-doc.

[stabilityLevel]

String

-

The default stability level used at provisioning time to generate configuration and provision packages. Can’t be used when config-stability-level or package-stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: stability-level.

[taskProps]

Map

-

Various properties that will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties.
NOTE: values of this parameter will overwrite the corresponding values from task-properties-file parameter, in case it’s also set. +
Alias is: task-properties.

[taskPropsFile]

File

-

Path to a properties file content of which will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties file that is used as the source of properties during file copying tasks with property replacement.
Alias is: task-properties-file.

[translateToFpl]

Boolean

-

By default generated build config dependencies are expressed using GAV, set this parameter to true to generate FPL.
Default value is: false.
Alias is: translate-to-fpl.

[wildflyChannelResolutionMode]

WildFlyChannelResolutionMode

-

Feature-pack WildFly channel resolution mode when WildFly channels are configured in the provisioning tooling used to provision this feature-pack. "NOT_REQUIRED" means that the feature-pack and artifacts can be resolved without WildFly channels. "REQUIRED" means that the feature-pack and all its artifacts must be only resolved from WildFly channels. "REQUIRED_FP_ONLY" means that only the feature-pack must be only resolved from WildFly channels. Referenced artifacts can be resolved outside of configured WildFly channels.
Default value is: NOT_REQUIRED.
User property is: wildfly.feature.pack.require.channel.resolution.
Alias is: wildfly-channel-resolution-mode.

3.3.4. Parameter Details

addFeaturePacksAsRequiredManifests
Add any feature-pack dependency as a required manifest in the manifest YAML definition. This parameter has no effect if "generate-channel-manifest" is false.

  • Type: boolean

  • Required: No

  • Default: true

  • Alias: add-feature-packs-as-required-manifests

buildName
The directory for the built artifact.

  • Type: java.lang.String

  • Required: No

  • User Property: wildfly.user.feature.pack.buildName

  • Default: ${project.build.directory}

configDir
The feature-pack build configuration file directory

  • Type: java.io.File

  • Required: No

  • User Property: wildfly.user.feature.pack.configDir

  • Default: ${basedir}

  • Alias: config-dir

configFile
The feature-pack build configuration file.

  • Type: java.lang.String

  • Required: No

  • User Property: wildfly.user.feature.pack.configFile

  • Default: wildfly-user-feature-pack-build.xml

  • Alias: config-file

configStabilityLevel
The default stability level used at provisioning time to generate configuration. Can’t be used when stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: config-stability-level

copyright
(no description)

  • Type: java.lang.String

  • Required: No

  • User Property: wildfly.feature.pack.copyright

  • Alias: copyright

cpeResolutionMode
If the WildFly product-conf artifact contains a CPE, the provisioned maven artifacts of other feature-packs present in the provisioning configuration are not added to the generated SBOM. In order to advertise that a feature-pack is in the scope of the WildFly CPE, set this parameter to SERVER_PRODUCT_CONF. If no CPE is defined, then the content of feature-packs are added to the generated SBOM whatever the value of this parameter.

  • Type: org.wildfly.galleon.plugin.CpeResolutionMode

  • Required: No

  • User Property: wildfly.sbom.sbom-cpe-resolution-mode

  • Default: LOCAL

  • Alias: sbom-cpe-resolution-mode

deployChannelManifest
(no description)

  • Type: boolean

  • Required: No

  • User Property: wildfly.feature.pack.deploy-channel-manifest

  • Default: true

  • Alias: deploy-channel-manifest

forbidLowerStatibilityLevelPackageReference
Enforce that no package at a lower stability level than the minimum-stability-level is referenced from Galleon constructs.

  • Type: boolean

  • Required: No

  • Default: false

  • Alias: forbid-lower-stability-level-package-reference

fpLocation
The FPL for the generated feature-pack.

  • Type: java.lang.String

  • Required: No

  • Default: ${project.groupId}:${project.artifactId}:${project.version}

  • Alias: feature-pack-location

generateChannelManifest
Generates a channel manifest YAML definition when the feature-pack is produced. Any dependency from the feature-pack is declared as a stream in the channel manifest.

  • Type: boolean

  • Required: No

  • User Property: wildfly.feature.pack.generate-channel-manifest

  • Default: false

  • Alias: generate-channel-manifest

generateCompleteModel
(no description)

  • Type: java.lang.Boolean

  • Required: Yes

  • Default: false

  • Alias: generate-complete-model

includeIncompleCoordsArtifactsInSbom
(no description)

  • Type: java.lang.Boolean

  • Required: No

  • User Property: wildfly.sbom.include-incomplete-coords-artifacts-in-sbom

  • Default: false

  • Alias: include-incomplete-coords-artifacts-in-sbom

minimumStabilityLevel
The minimum stability level of the WildFly processes used to generate feature specs and include packages. Set this if you need to generate feature specs for features with a lower stability level than the default level of the WildFly process being used for feature-spec generation. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: minimum-stability-level

packageStabilityLevel
The default stability level used at provisioning time when installing packages/JBoss Modules modules. Can’t be used when stability-level is set. If both the config-stability-level and the package-stability-level options are set, the level of the package-stability-level option must imply the level of the config-stability-level option. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: package-stability-level

releaseName
The name of the release the feature-pack represents which will be stored in the feature-pack’s resources/wildfly/wildfly-tasks.properties as product.release.name property.

  • Type: java.lang.String

  • Required: No

  • Default: ${product.release.name}

  • Alias: release-name

resourcesDir
Represents the directory containing child directories packages, feature_groups, modules etc. Either an absolute path or a path relative to configDir.

  • Type: java.lang.String

  • Required: Yes

  • User Property: wildfly.user.feature.pack.resourcesDir

  • Default: src/main/resources

  • Alias: resources-dir

skipDoc
(no description)

  • Type: boolean

  • Required: No

  • User Property: wildfly.feature.pack.skip-doc

  • Default: false

  • Alias: skip-doc

stabilityLevel
The default stability level used at provisioning time to generate configuration and provision packages. Can’t be used when config-stability-level or package-stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: stability-level

taskProps
Various properties that will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties.
NOTE: values of this parameter will overwrite the corresponding values from task-properties-file parameter, in case it’s also set.

  • Type: java.util.Map

  • Required: No

  • Alias: task-properties

taskPropsFile
Path to a properties file content of which will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties file that is used as the source of properties during file copying tasks with property replacement.

  • Type: java.io.File

  • Required: No

  • Alias: task-properties-file

translateToFpl
By default generated build config dependencies are expressed using GAV, set this parameter to true to generate FPL.

  • Type: java.lang.Boolean

  • Required: No

  • Default: false

  • Alias: translate-to-fpl

wildflyChannelResolutionMode
Feature-pack WildFly channel resolution mode when WildFly channels are configured in the provisioning tooling used to provision this feature-pack. "NOT_REQUIRED" means that the feature-pack and artifacts can be resolved without WildFly channels. "REQUIRED" means that the feature-pack and all its artifacts must be only resolved from WildFly channels. "REQUIRED_FP_ONLY" means that only the feature-pack must be only resolved from WildFly channels. Referenced artifacts can be resolved outside of configured WildFly channels.

  • Type: org.wildfly.galleon.plugin.WildFlyChannelResolutionMode

  • Required: No

  • User Property: wildfly.feature.pack.require.channel.resolution

  • Default: NOT_REQUIRED

  • Alias: wildfly-channel-resolution-mode

3.3.5. Plugin configuration

Dependency on WildFly

The pom.xml of the project that makes use of this plugin must express a dependency on the WildFly feature-pack it is depending upon.

Feature-pack configuration

For typical user feature-packs construct (eg: package JBoss modules and define galleon layers), there is no need to define a feature-pack build configuration file. Everything can be configured from the plugin configuration element inside the pom.xml file.

For more advanced configuration, a file named wildfly-user-feature-pack-build.xml can be defined in the project root dir. This file complies with the wildfly-feature-pack-build.xml file syntax but only supports a subset of it.

The following items can be defined:

  • Feature Pack Location of the feature-pack.

  • Dependencies (transitives or directs) on other feature-packs.

  • Default packages.

For example:

<build xmlns="urn:wildfly:feature-pack-build:3.0" producer="org.foo:my-galleon-pack:1.0.0.Final">
    <dependencies>
        <dependency location="wildfly@maven(org.jboss.universe:community-universe):current#17.0.0.Final">
            <default-configs inherit="false"/>
            <packages inherit="false"/>
        </dependency>
    </dependencies>
    <default-packages>
        <package name="my.package1"/>
    </default-packages>
</build>

3.3.6. Galleon feature-pack content that can be defined with the mojo

JBoss module packages

The directory src/main/resources/modules contains JBoss modules to be turned into feature-pack packages. A package is created per JBoss module. JBoss module dependencies are reflected in the corresponding package dependencies.

A module can contain the binaries it wants to see installed or rely on the 'module.xml template' capability of the mojo. For example, here is an excerpt from a module.xml template:

<?xml version="1.0" encoding="UTF-8"?>
<module name="org.postgresql.jdbc" xmlns="urn:jboss:module:1.8">
    <resources>
        <artifact name="${org.postgresql:postgresql}"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>

It looks pretty much like the final module.xml except that the artifact name is an expression which should be replaced with either the complete artifact coordinates in case of a thin distribution, e.g.

<?xml version="1.0" encoding="UTF-8"?>
<module name="org.postgresql.jdbc" xmlns="urn:jboss:module:1.8">
    <resources>
        <artifact name="org.postgresql:postgresql:9.4.1211"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>

or the resource-root element in case of a fat distribution, e.g.

<module name="org.postgresql.jdbc" xmlns="urn:jboss:module:1.8">

    <resources>
        <resource-root path="postgresql-9.4.1211.jar"/>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>

module.xml template processing is happening at provisioning time and depends on the kind of distribution being provisioned. That is controlled by the plugin option jboss-maven-dist=true|false. true to provision a thin installation, false to provision a fat installation.

If you are packaging JBoss module using the "module.xml template" you must express the dependencies on the actual artifacts you want to see provisioned in the pom.xml file.
It is possible that a module depends on another module which is not found in the current feature-pack. In that case, the feature-pack that contains the package representing the module from the dependency must be declared as the dependency of the current feature-pack in the feature-pack build config file. If the dependency could not be resolved locally (among the modules included in the current feature-pack), the module will be looked up in the dependencies of the current feature-pack (in the order the dependencies are specified in the feature-pack build config file).

In case a module dependency could not be resolved neither locally nor in the feature-pack dependencies, an error will be thrown with the corresponding message.

The package generated for a JBoss module can still be customized by, e.g., adding pm/wildfly/tasks.xml to it in src/main/resources/packages. In this case the package dir in src/main/resources/packages has to include only the content that the generated package is missing. It doesn’t have to include package.xml unless the generated one has to be replaced with a custom one.
Custom, add-ons and layers types of JBoss modules
  • Custom modules are defined directly under modules directory.

  • add-ons are defined under modules/system/add-ons/<add-on name> directory.

  • layers are defined under modules/system/layers/<layer name> directory. You must also define the file layers.conf under modules directory.

Galleon packages

The directory src/main/resources/packages/ contains galleon packages. Packages contain content (other than JBoss modules) you want to see provisioned along with a layer and/or configuration.

Documentation to help you define packages can be found here.

Galleon Layers

You can define your own layers (eg: drivers, datasources, customized subsystem) that can be then assembled with WildFly built-in layers to compose a configuration.

The directory src/main/resources/layers contains the layers definitions.

Layers are defined for a given model of configuration. Configuration model can be one of standalone, host or domain. The layers defined for a given configuration model are located inside a directory named with the configuration model: layers/<config model name>/<layer name>/layer-spec.xml

Example of a layer that defines the configuration for a mysql driver and include the driver package (a JBoss module) named com.mysql.jdbc.

<?xml version="1.0" ?>
<layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="mysql-driver">
    <feature spec="subsystem.datasources">
        <feature spec="subsystem.datasources.jdbc-driver">
            <param name="driver-name" value="mysql"/>
            <param name="jdbc-driver" value="mysql"/>
            <param name="driver-xa-datasource-class-name" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
            <param name="driver-module-name" value="com.mysql.jdbc"/>
        </feature>
    </feature>
    <packages>
        <package name="com.mysql.jdbc"/>
    </packages>
</layer-spec>

Documentation to help you define layers can be found here.

Galleon feature-groups

You can define your own feature-groups that can then be re-used when defining configurations.

The directory src/main/resources/feature_groups contains the feature-groups definitions. A feature-group is defined inside the file <feature-group name>.xml

For example:

<?xml version="1.0" encoding="UTF-8"?>
<feature-group-spec name="my-feature-group" xmlns="urn:jboss:galleon:feature-group:1.0">
    <feature-group name="another-feature-group"/>
    <feature spec="interface">
        <param name="interface" value="my-interface"/>
        <param name="inet-address" value="192.168.1.1"/>
    </feature>
</feature-group-spec>

Documentation to help you define feature-groups can be found here.

Galleon default configurations

You can define default configurations to be provisioned by galleon. Default configurations are defined in src/main/resources/configs/<config model>/<config name>/config.xml file. Configuration model can be one of standalone, host or domain.

For example:

<config xmlns="urn:jboss:galleon:config:1.0" name="standalone.xml" model="standalone">
    <layers>
        <include name="cloud-profile"/>
        <include name="my-layer"/>
    </layers>
    <feature-group name="my-feature-group"/>
</config>

Documentation to help you define default configurations can be found here.

3.4. build-feature-pack

3.4.1. wildfly-galleon:build-feature-pack

Full name: org.wildfly.galleon-plugins:wildfly-galleon-maven-plugin:8.2.2.Final:build-feature-pack

3.4.2. Description

This Maven mojo creates a WildFly style feature-pack archive from the provided resources according to the feature-pack build configuration file and attaches it to the current Maven project as an artifact. The content of the future feature-pack archive is first created in the directory called layout under the module’s build directory which is then ZIPped to create the feature-pack artifact.

3.4.3. Attributes

  • Requires a Maven project to be executed.

  • Requires dependency resolution of artifacts in scope: compile+runtime.

  • Binds by default to the lifecycle phase: compile.

Table 5. Required Parameters

Name

Type

Since

Description

[featureSpecsOutput]

File

-

The directory where the generated feature specs are written.
Default value is: ${project.build.directory}/resources/features.
Alias is: feature-specs-output.

[generateCompleteModel]

Boolean

-

(no description)
Default value is: false.
Alias is: generate-complete-model.

[moduleTemplatesDir]

File

-

Used only for feature spec generation and points to a directory where the module templates from the dependent feature-packs are gathered before they are transformed and copied under their default destination wildflyHome/modules. Intended mainly for debugging.
Default value is: ${project.build.directory}/module-templates.
User property is: wfgp.moduleTemplatesDir.
Alias is: module-templates.

[resourcesDir]

String

-

Represents the directory containing child directories packages, feature_groups, modules etc. Either an absolute path or a path relative to configDir.
Default value is: src/main/resources.
User property is: wildfly.feature.pack.resourcesDir.
Alias is: resources-dir.

[wildflyHome]

File

-

Used only for feature spec generation and points to a directory from which the embedded WildFly instance will be started that is used for exporting the meta-model. Intended mainly for debugging.
Default value is: ${project.build.directory}/wildfly.
User property is: wfgp.wildflyHome.
Alias is: wildfly-home.

Table 6. Optional Parameters

Name

Type

Since

Description

[addFeaturePacksAsRequiredManifests]

boolean

-

Add any feature-pack dependency as a required manifest in the manifest YAML definition. This parameter has no effect if "generate-channel-manifest" is false.
Default value is: true.
Alias is: add-feature-packs-as-required-manifests.

[buildName]

String

-

The directory for the built artifact.
Default value is: ${project.build.directory}.
User property is: wildfly.feature.pack.buildName.

[configDir]

File

-

The feature-pack build configuration file directory
Default value is: ${basedir}.
User property is: wildfly.feature.pack.configDir.
Alias is: config-dir.

[configFile]

String

-

The feature-pack build configuration file.
Default value is: wildfly-feature-pack-build.xml.
User property is: wildfly.feature.pack.configFile.
Alias is: config-file.

[configStabilityLevel]

String

-

The default stability level used at provisioning time to generate configuration. Can’t be used when stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: config-stability-level.

[copyright]

String

-

(no description)
User property is: wildfly.feature.pack.copyright.
Alias is: copyright.

[cpeResolutionMode]

CpeResolutionMode

-

If the WildFly product-conf artifact contains a CPE, the provisioned maven artifacts of other feature-packs present in the provisioning configuration are not added to the generated SBOM. In order to advertise that a feature-pack is in the scope of the WildFly CPE, set this parameter to SERVER_PRODUCT_CONF. If no CPE is defined, then the content of feature-packs are added to the generated SBOM whatever the value of this parameter.
Default value is: LOCAL.
User property is: wildfly.sbom.sbom-cpe-resolution-mode.
Alias is: sbom-cpe-resolution-mode.

[deployChannelManifest]

boolean

-

(no description)
Default value is: true.
User property is: wildfly.feature.pack.deploy-channel-manifest.
Alias is: deploy-channel-manifest.

[forbidLowerStatibilityLevelPackageReference]

boolean

-

Enforce that no package at a lower stability level than the minimum-stability-level is referenced from Galleon constructs.
Default value is: false.
Alias is: forbid-lower-stability-level-package-reference.

[forkEmbedded]

boolean

-

Used only for feature spec generation and indicates whether to launch the embedded server to read feature descriptions in a separate process
Alias is: fork-embedded.

[fpArtifactId]

String

-

The artifactId for the generated feature-pack.
Default value is: ${project.artifactId}.
Alias is: feature-pack-artifact-id.

[generateChannelManifest]

boolean

-

Generates a channel manifest YAML definition when the feature-pack is produced. Any dependency from the feature-pack is declared as a stream in the channel manifest.
Default value is: false.
User property is: wildfly.feature.pack.generate-channel-manifest.
Alias is: generate-channel-manifest.

[includeIncompleCoordsArtifactsInSbom]

Boolean

-

(no description)
Default value is: false.
User property is: wildfly.sbom.include-incomplete-coords-artifacts-in-sbom.
Alias is: include-incomplete-coords-artifacts-in-sbom.

[minimumStabilityLevel]

String

-

The minimum stability level of the WildFly processes used to generate feature specs and include packages. Set this if you need to generate feature specs for features with a lower stability level than the default level of the WildFly process being used for feature-spec generation. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: minimum-stability-level.

[packageStabilityLevel]

String

-

The default stability level used at provisioning time when installing packages/JBoss Modules modules. Can’t be used when stability-level is set. If both the config-stability-level and the package-stability-level options are set, the level of the package-stability-level option must imply the level of the config-stability-level option. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: package-stability-level.

[releaseName]

String

-

The name of the release the feature-pack represents which will be stored in the feature-pack’s resources/wildfly/wildfly-tasks.properties as product.release.name property.
Default value is: ${product.release.name}.
Alias is: release-name.

[skipDoc]

boolean

-

(no description)
Default value is: false.
User property is: wildfly.feature.pack.skip-doc.
Alias is: skip-doc.

[stabilityLevel]

String

-

The default stability level used at provisioning time to generate configuration and provision packages. Can’t be used when config-stability-level or package-stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.
Alias is: stability-level.

[taskProps]

Map

-

Various properties that will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties.
NOTE: values of this parameter will overwrite the corresponding values from task-properties-file parameter, in case it’s also set. +
Alias is: task-properties.

[taskPropsFile]

File

-

Path to a properties file content of which will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties file that is used as the source of properties during file copying tasks with property replacement.
Alias is: task-properties-file.

[wildflyChannelResolutionMode]

WildFlyChannelResolutionMode

-

Feature-pack WildFly channel resolution mode when WildFly channels are configured in the provisioning tooling used to provision this feature-pack. "NOT_REQUIRED" means that the feature-pack and artifacts can be resolved without WildFly channels. "REQUIRED" means that the feature-pack and all its artifacts must be only resolved from WildFly channels. "REQUIRED_FP_ONLY" means that only the feature-pack must be only resolved from WildFly channels. Referenced artifacts can be resolved outside of configured WildFly channels.
Default value is: NOT_REQUIRED.
User property is: wildfly.feature.pack.require.channel.resolution.
Alias is: wildfly-channel-resolution-mode.

3.4.4. Parameter Details

addFeaturePacksAsRequiredManifests
Add any feature-pack dependency as a required manifest in the manifest YAML definition. This parameter has no effect if "generate-channel-manifest" is false.

  • Type: boolean

  • Required: No

  • Default: true

  • Alias: add-feature-packs-as-required-manifests

buildName
The directory for the built artifact.

  • Type: java.lang.String

  • Required: No

  • User Property: wildfly.feature.pack.buildName

  • Default: ${project.build.directory}

configDir
The feature-pack build configuration file directory

  • Type: java.io.File

  • Required: No

  • User Property: wildfly.feature.pack.configDir

  • Default: ${basedir}

  • Alias: config-dir

configFile
The feature-pack build configuration file.

  • Type: java.lang.String

  • Required: No

  • User Property: wildfly.feature.pack.configFile

  • Default: wildfly-feature-pack-build.xml

  • Alias: config-file

configStabilityLevel
The default stability level used at provisioning time to generate configuration. Can’t be used when stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: config-stability-level

copyright
(no description)

  • Type: java.lang.String

  • Required: No

  • User Property: wildfly.feature.pack.copyright

  • Alias: copyright

cpeResolutionMode
If the WildFly product-conf artifact contains a CPE, the provisioned maven artifacts of other feature-packs present in the provisioning configuration are not added to the generated SBOM. In order to advertise that a feature-pack is in the scope of the WildFly CPE, set this parameter to SERVER_PRODUCT_CONF. If no CPE is defined, then the content of feature-packs are added to the generated SBOM whatever the value of this parameter.

  • Type: org.wildfly.galleon.plugin.CpeResolutionMode

  • Required: No

  • User Property: wildfly.sbom.sbom-cpe-resolution-mode

  • Default: LOCAL

  • Alias: sbom-cpe-resolution-mode

deployChannelManifest
(no description)

  • Type: boolean

  • Required: No

  • User Property: wildfly.feature.pack.deploy-channel-manifest

  • Default: true

  • Alias: deploy-channel-manifest

featureSpecsOutput
The directory where the generated feature specs are written.

  • Type: java.io.File

  • Required: Yes

  • Default: ${project.build.directory}/resources/features

  • Alias: feature-specs-output

forbidLowerStatibilityLevelPackageReference
Enforce that no package at a lower stability level than the minimum-stability-level is referenced from Galleon constructs.

  • Type: boolean

  • Required: No

  • Default: false

  • Alias: forbid-lower-stability-level-package-reference

forkEmbedded
Used only for feature spec generation and indicates whether to launch the embedded server to read feature descriptions in a separate process

  • Type: boolean

  • Required: No

  • Alias: fork-embedded

fpArtifactId
The artifactId for the generated feature-pack.

  • Type: java.lang.String

  • Required: No

  • Default: ${project.artifactId}

  • Alias: feature-pack-artifact-id

generateChannelManifest
Generates a channel manifest YAML definition when the feature-pack is produced. Any dependency from the feature-pack is declared as a stream in the channel manifest.

  • Type: boolean

  • Required: No

  • User Property: wildfly.feature.pack.generate-channel-manifest

  • Default: false

  • Alias: generate-channel-manifest

generateCompleteModel
(no description)

  • Type: java.lang.Boolean

  • Required: Yes

  • Default: false

  • Alias: generate-complete-model

includeIncompleCoordsArtifactsInSbom
(no description)

  • Type: java.lang.Boolean

  • Required: No

  • User Property: wildfly.sbom.include-incomplete-coords-artifacts-in-sbom

  • Default: false

  • Alias: include-incomplete-coords-artifacts-in-sbom

minimumStabilityLevel
The minimum stability level of the WildFly processes used to generate feature specs and include packages. Set this if you need to generate feature specs for features with a lower stability level than the default level of the WildFly process being used for feature-spec generation. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: minimum-stability-level

moduleTemplatesDir
Used only for feature spec generation and points to a directory where the module templates from the dependent feature-packs are gathered before they are transformed and copied under their default destination wildflyHome/modules. Intended mainly for debugging.

  • Type: java.io.File

  • Required: Yes

  • User Property: wfgp.moduleTemplatesDir

  • Default: ${project.build.directory}/module-templates

  • Alias: module-templates

packageStabilityLevel
The default stability level used at provisioning time when installing packages/JBoss Modules modules. Can’t be used when stability-level is set. If both the config-stability-level and the package-stability-level options are set, the level of the package-stability-level option must imply the level of the config-stability-level option. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: package-stability-level

releaseName
The name of the release the feature-pack represents which will be stored in the feature-pack’s resources/wildfly/wildfly-tasks.properties as product.release.name property.

  • Type: java.lang.String

  • Required: No

  • Default: ${product.release.name}

  • Alias: release-name

resourcesDir
Represents the directory containing child directories packages, feature_groups, modules etc. Either an absolute path or a path relative to configDir.

  • Type: java.lang.String

  • Required: Yes

  • User Property: wildfly.feature.pack.resourcesDir

  • Default: src/main/resources

  • Alias: resources-dir

skipDoc
(no description)

  • Type: boolean

  • Required: No

  • User Property: wildfly.feature.pack.skip-doc

  • Default: false

  • Alias: skip-doc

stabilityLevel
The default stability level used at provisioning time to generate configuration and provision packages. Can’t be used when config-stability-level or package-stability-level is set. It overrides the value set in the wildfly-feature-pack-build.xml file.

  • Type: java.lang.String

  • Required: No

  • Alias: stability-level

taskProps
Various properties that will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties.
NOTE: values of this parameter will overwrite the corresponding values from task-properties-file parameter, in case it’s also set.

  • Type: java.util.Map

  • Required: No

  • Alias: task-properties

taskPropsFile
Path to a properties file content of which will be added to feature-pack’s resources/wildfly/wildfly-tasks.properties file that is used as the source of properties during file copying tasks with property replacement.

  • Type: java.io.File

  • Required: No

  • Alias: task-properties-file

wildflyChannelResolutionMode
Feature-pack WildFly channel resolution mode when WildFly channels are configured in the provisioning tooling used to provision this feature-pack. "NOT_REQUIRED" means that the feature-pack and artifacts can be resolved without WildFly channels. "REQUIRED" means that the feature-pack and all its artifacts must be only resolved from WildFly channels. "REQUIRED_FP_ONLY" means that only the feature-pack must be only resolved from WildFly channels. Referenced artifacts can be resolved outside of configured WildFly channels.

  • Type: org.wildfly.galleon.plugin.WildFlyChannelResolutionMode

  • Required: No

  • User Property: wildfly.feature.pack.require.channel.resolution

  • Default: NOT_REQUIRED

  • Alias: wildfly-channel-resolution-mode

wildflyHome
Used only for feature spec generation and points to a directory from which the embedded WildFly instance will be started that is used for exporting the meta-model. Intended mainly for debugging.

  • Type: java.io.File

  • Required: Yes

  • User Property: wfgp.wildflyHome

  • Default: ${project.build.directory}/wildfly

  • Alias: wildfly-home

3.4.5. Feature-pack packages

The Maven project module which creates a feature-pack may describe its packages and/or provide more data for the packages generated from JBoss modules in the Maven module’s src/main/resources/packages.

Every child directory of src/main/resources/packages represents a package with the directory name being the package name. The content of the package directory is going to be copied to the corresponding package directory in the feature-pack.

The usual package directory structure is:

package_name
|- content/
|- pm/
|  `- wildfly/
|     `- tasks.xml
`- package.xml

In general, the only required child of the package directory is package.xml.

Package content directory includes content that will be copied to the installation root directory when the package is installed.

pm/wildfly/tasks.xml file is optional, it may include instructions to copy and/or delete files and directories, create directories, resolve and copy Maven artifacts to the installation directory, etc. These tasks are executed when the content of all the packages has been copied into the installation.

The tasks XML schema contains the definition of the tasks you can add to the tasks.xml file. This example of tasks.xml file contains the set of tasks one can use in a tasks.xml file.

3.4.6. Generating JBoss module packages

JBoss modules of the distribution are turned into feature-pack packages. A package is created per JBoss module. JBoss module dependencies are reflected in the corresponding package dependencies.

JBoss modules packages don’t have to be manually described in src/main/resources/packages.

Traditionally, WildFly-based builds use module.xml templates to generate the final module.xml files based on the distribution type selected: thin (when the JBoss module artifacts are loaded directly from the Maven repository at runtime) or thick (when the JBoss module artifacts are resolved and copied to the distribution directory at provisioning time).

The Maven module that is building a feature-pack may include src/main/resources/modules/system/layers directory containing module.xml templates. The mojo will read those and generate a package per module.xml.

For example, here is an excerpt from a module.xml template:

<module xmlns="urn:jboss:module:1.8" name="org.jboss.as.jmx">
    <properties>
        <property name="jboss.api" value="private"/>
    </properties>

    <exports>
        <exclude path="org/jboss/as/jmx/logging"/>
    </exports>

    <resources>
        <artifact name="${org.wildfly.core:wildfly-jmx}"/>
    </resources>

    <dependencies>
        <!-- skipped content -->

It looks pretty much like the final module.xml except that the artifact name is an expression which should be replaced with either the complete artifact coordinates in case of a thin distribution, e.g.

<module name="org.jboss.as.jmx" xmlns="urn:jboss:module:1.8">
    <properties>
        <property name="jboss.api" value="private"/>
    </properties>

    <exports>
        <exclude path="org/jboss/as/jmx/logging"/>
    </exports>

    <resources>
        <artifact name="org.wildfly.core:wildfly-jmx:5.0.0.Beta3-SNAPSHOT"/>
    </resources>

    <dependencies>
        <!-- skipped content -->

or the resource-root element in case of a thick distribution, e.g.

<module name="org.jboss.as.jmx" xmlns="urn:jboss:module:1.8">
    <properties>
        <property name="jboss.api" value="private"/>
    </properties>

    <exports>
        <exclude path="org/jboss/as/jmx/logging"/>
    </exports>

    <resources>
        <resource-root path="wildfly-jmx-5.0.0.Beta3-SNAPSHOT.jar"/>
    </resources>

    <dependencies>
        <!-- skipped content -->

module.xml template processing is happening at provisioning time and depends on the kind of distribution being provisioned.

It is possible that a module depends on another module which is not found in the current feature-pack. In that case, the feature-pack that contains the package representing the module from the dependency must be declared as the dependency of the current feature-pack in the feature-pack build config file. If the dependency could not be resolved locally (among the modules included in the current feature-pack), the module will be looked up in the dependencies of the current feature-pack (in the order the dependencies are specified in the feature-pack build config file).

In case a module dependency could not be resolved neither locally nor in the feature-pack dependencies, an error will be thrown with the corresponding message.

The package generated for a JBoss module can still be customized by, e.g., adding pm/wildfly/tasks.xml to it in src/main/resources/packages. In this case the package dir in src/main/resources/packages has to include only the content that the generated package is missing. It doesn’t have to include package.xml unless the generated one has to be replaced with a custom one.
modules.all package

If a feature-pack includes JBoss modules, in addition to the module packages, the mojo will generate a package called modules.all. This package will not contain any content but will simply depend on all the module packages generated for this feature-pack. This package exists for convenience only to be able to install all the modules from the feature-pack (and its dependencies) by including a single package.

Original WildFly feature-packs include modules.all into the default package list at the moment to follow the legacy approach of building distributions. This is configured in the feature-pack build config file.

3.5. Using the plugin as a Maven Extension

Your project can be configured to use the plugin as a Maven extension. If you do this, Maven will allow you to use one of two new packaging types for your Maven module: galleon-feature-pack or galleon-user-feature-pack. You would use these instead of the pom packaging that’s typically used.

There are two main benefits of doing this:

  • It results in a default package phase execution of this plugin’s build-feature-pack or build-user-feature-pack goal, saving you the XML boilerplate of specifying executions and an execution id, goal and phase.

  • It results in the plugin using the built feature-pack as the main artifact of the project build, instead of attaching it as an additional artifact with a null Maven classifier. Doing it this way avoids problems some other plugins have with additional attachments with a null qualifier.

To tell Maven to use the plugin as a Maven extension, in the plugin declaration include the extensions element with a value of true:

<plugin>
    <groupId>org.wildfly.galleon-plugins</groupId>
    <artifactId>wildfly-galleon-maven-plugin</artifactId>
    <extensions>true</extensions>

3.5.1. Packaging type galleon-feature-pack

Use this packaging type when you wish to use the build-feature-pack goal. To use it, configure the pom’s top-level packaging element:

<packaging>galleon-feature-pack</packaging>

When this packaging type is used, Maven will execute default plugins in the package, install and deploy phases (assuming the command to launch maven enables those phases). It will also execute any other plugins configured in your pom.

If you are migrating a pom that used any packaging value other than pom (for example jar), plugin executions for other phases that previously happened by default will no longer happen and will need to be manually declared in the pom.

The important thing here is the default plugin execution for the package phase is this plugin’s build-feature-pack goal. That goal will be executed, using whatever configuration is specified for the default-build-feature-pack execution id.

If you are using the galleon-feature-pack packaging type, use default-build-feature-pack as the execution id in the plugin configuration. Better yet, skip the executions element boilerplate and place any configuration element directly under the plugin root.

An example plugin configuration might look like this:

<plugin>
    <groupId>org.wildfly.galleon-plugins</groupId>
    <artifactId>wildfly-galleon-maven-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <fork-embedded>true</fork-embedded>
        <generate-channel-manifest>true</generate-channel-manifest>
        <minimum-stability-level>preview</minimum-stability-level>
        <config-stability-level>preview</config-stability-level>
        <package-stability-level>preview</package-stability-level>
    </configuration>
</plugin>

3.5.2. Packaging type galleon-user-feature-pack

Use this packaging type when you wish to use the build-user-feature-pack goal. To use it, configure the pom’s top-level packaging element:

<packaging>galleon-user-feature-pack</packaging>

When this packaging type is used, Maven will execute default plugins in the package, install and deploy phases (assuming the command to launch maven enables those phases). It will also execute any other plugins configured in your pom.

If you are migrating a pom that used any packaging value other than pom (for example jar), plugin executions for other phases that previously happened by default will no longer happen and will need to be manually declared in the pom.

The important thing here is the default plugin execution for the package phase is this plugin’s build-user-feature-pack goal. That goal will be executed, using whatever configuration is specified for the default-build-user-feature-pack execution id.

If you are using the galleon-user-feature-pack packaging type, use default-user-build-feature-pack as the execution id in the plugin configuration. Better yet, skip the executions element boilerplate and place any configuration element directly under the plugin root.

3.6. Feature-pack build config file (wildfly-feature-pack-build.xml)

Feature-pack building starts with this file. The file describes the feature-pack in terms of its dependencies on other feature-packs, default packages, configs and other options such as from which artifact groups to extract schemas into the distribution’s docs/schema directory.

If the file includes feature-pack dependencies, those feature-packs must be resolvable as Maven artifacts during the build process. They will be explored to collect the provisioning descriptions (such as feature-pack.xml, etc) of the dependencies.

Normally, most of the content of this file will be copied directly into the final feature-pack.xml generated by the mojo. Here is an example from WildFly Servlet feature-pack build config file

<build xmlns="urn:wildfly:feature-pack-build:3.0" producer="wildfly-servlet@maven(org.jboss.universe:community-universe):current">
    <dependencies>
        <dependency group-id="org.wildfly.core" artifact-id="wildfly-core-galleon-pack">
            <name>org.wildfly.core:wildfly-core-galleon-pack</name>
            <packages inherit="false">
                <exclude name="product.conf"/>
            </packages>
            <default-configs inherit="false"/>
        </dependency>
    </dependencies>
    <default-packages>
        <package name="modules.all"/>
        <package name="docs"/>
    </default-packages>
    <package-schemas>
        <group name="org.jboss.as"/>
        <group name="org.wildfly"/>
        <group name="org.wildfly.core"/>
    </package-schemas>
    <config model="standalone">
        <packages>
            <package name="product.conf" optional="true"/>
            <package name="misc.standalone"/>
        </packages>
    </config>

    <!-- other configs are skipped -->

    <generate-feature-specs>
        <extensions>
            <standalone>
                <extension>org.jboss.as.ee</extension>
                <extension>org.jboss.as.naming</extension>
                <extension>org.jboss.as.security</extension>
                <extension>org.wildfly.extension.undertow</extension>
            </standalone>
            <domain>
                <extension>org.jboss.as.ee</extension>
                <extension>org.jboss.as.naming</extension>
                <extension>org.jboss.as.security</extension>
                <extension>org.wildfly.extension.undertow</extension>
            </domain>
        </extensions>
    </generate-feature-specs>
</build>

All the elements in the above example except for package-schemas and generate-feature-specs are actual feature-pack.xml content that will be copied to the resulting feature-pack.xml as-is.

Extracting schemas

The presence of element package-schemas instructs the mojo to create a package called docs.schema. The package includes no content but a file with Maven artifact groupIds from which XSD schemas should be extracted into the distribution’s docs/schema directory, in case docs.schema package was selected to be installed (it is by default).

Feature specs generation

Feature-pack may or may not include feature specs (XML files describing configuration features). Feature specs are included only if the feature-pack includes one or more subsystems that should be added to the confuration when the feature-pack is installed.

In WildFly feature-packs, feature specs are generated. generate-feature-specs is an element that lists extensions included in the feature-pack for which feature specs should be generated.

feature specs are generated using generate-feature-specs goal of the plugin.
Adding provisioning plugins

Feature-packs that depend on WildFly (or WildFly Core), normally, don’t need to add any provisioning plugins to be usable by Galleon. WildFly Core feature-pack includes the plugins that are used during provisioning for all the feature-packs that (directly or indirectly) depend on it. Here is a snipped from WildFly Core wildfly-feature-pack-build.xml that adds WildFly provisioning plugin JARs:

<build xmlns="urn:wildfly:feature-pack-build:3.0" producer="wildfly-core@maven(org.jboss.universe:community-universe):current">
    <!-- content skipped -->

    <plugins>
        <plugin artifact="org.wildfly.galleon-plugins:wildfly-galleon-plugins"/> (1)
    </plugins>

    <resources>
        <copy artifact="org.wildfly.galleon-plugins:wildfly-config-gen" to="wildfly/wildfly-config-gen.jar"/> (2)
    </resources>

    <!-- content skipped -->
</build>
1 plugins element may include multiple plugin elements specifying Maven artifact coordinates of the plugin
2 copy element under resources instructs to copy the specified artifact to the feature-pack resources directory
Both artifact coordinates above are missing versions. Although the versions could specified, in this case they will be resolved from the Maven project dependencies at the plugin execution time.
Configuring stability levels

This feature requires a minimum schema version of 3.4.

Stability levels can be set using the following elements:

<stability-levels>
  <!-- The minimum stability level of the WildFly processes used to generate feature specs and include packages. -->
  <minimum-stability-level>[default|community|preview|experimental]</minimum-stability-level>
  <!-- The default stability level used at provisioning time to generate configuration. -->
  <config-stability-level>[default|community|preview|experimental]</config-stability-level>
  <!-- The default stability level used at provisioning time when installing packages/JBoss Modules modules. -->
  <package-stability-level>[default|community|preview|experimental]</package-stability-level>
</stability-levels>
Instead of using <config-stability-level> and <package-stability-level> you can set the <stability-level> element that applies to both configurations and packages.
If the <config-stability-level> and the <package-stability-level> are set, then the level of the <package-stability-level> must imply the level of the <config-stability-level>.
Stability options set in the Maven Plugin override the values set in the file.
Feature-pack family and criteria

A feature-pack can be part of a family and expose some criteria it is implementing. Add the following XML element to make the feature-pack be part of a family:

...
 <family name="myfamily">
   <criteria name="feature1"/>
   <criteria name="feature2"/>
 </family>
...

Note that at least one criteria element is required.

Dependency on any member of a feature-pack family

A feature-pack can be part of a family and implement some criteria. Members of the family that implement the same criteria can be used at provisioning time in place of other members. By default, a feature-pack expresses a dependency on a given feature-pack. To allow to depend on any member of the feature-pack family that offers the expected criteria, you can use the allowedFamily attribute. For example:

...
 <dependency group-id="org.wildfly.core" artifact-id="wildfly-core-galleon-pack" allowedFamily="wildfly+jakarta-ee">
 ...
 </dependency>
...

Note that all the criteria found in the allowedFamily attribute are added to this feature-pack if the family is the same. The added criteria are tagged 'inherited'.