# Quarkus Extension Metadata

Quarkus extensions are distributed as Maven JAR artifacts that application and other libraries may depend on. When a Quarkus application project is built, tested or edited using the Quarkus dev tools, Quarkus extension JAR artifacts will be identified on the application classpath by the presence of the Quarkus extension metadata files in them. This document describes the purpose of each Quarkus extension metadata file and its content.

| Two of the metadata files have the same name but different extensions, `quarkus-extension.yaml` and `quarkus-extension.properties`. It is easy to mix them up, be careful. You will usually edit the YAML file and track it in your SCM. While you can manually manage the properties file, Quarkus will generate it at build if you don’t.

## META-INF/quarkus-extension.yaml

Every runtime extension artifact must include this file. This file is used by Quarkus dev tools when displaying information about an extension, creating a new project or adding extensions to an existing project, etc. This file isn’t used at application build or bootstrap times. The basic and required metadata included in this file can be generated by the Quarkus Maven and Gradle plugins when the extension artifact is built. However, typically, extension authors will want to provide more information about the extension to the Quarkus dev tools and users. The extra information could be provided in a template `META-INF/quarkus-extension.yaml` found in the extension runtime module’s resources directory, e.g. `src/main/resources/META-INF/quarkus-extension.yaml`. Here is an example of such a template for the `quarkus-resteasy-reactive` extension:

    name: "REST" (1)
    artifact: ${project.groupId}:${project.artifactId}:${project.version} (2)
    metadata:
      short-name: "rest" (3)
      keywords: (4)
      - "jaxrs"
      - "web"
      - "rest"
      categories: (5)
      - "web"
      - "reactive"
      status: "stable" (6)
      guide: "https://quarkus.io/guides/rest" (7)
      icon-url: "https://quarkus.io/assets/images/about/icon-reactive.svg" (8)
      codestart: (9)
        name: "rest"
        languages:
          - "java"
          - "kotlin"
          - "scala"
        artifact: "io.quarkus:quarkus-project-core-extension-codestarts"
      config: (10)
      - "quarkus.rest."

1 | Extension name displayed to users
2 | Extension runtime artifact expression that will be replaced with the actual coordinates during the build, this field could be omitted
3 | Short name that could be used to quickly locate an extension in the catalog of extensions provided by the dev tools to the users
4 | Keywords that can be used to search for extensions in the extension catalog provided by the dev tools to the users
5 | Categories the extension should appear under on code.quarkus.io. This field can be omitted, the extension will still be listed on code.quarkus.io but won’t be categorized
6 | Maturity status that could be `stable`, `preview`, `experimental`. It is up to extension maintainers to evaluate the maturity status and communicate it to the users
7 | Link to the extension guide or documentation page
8 | Link to an externally hosted image. This is used in the Quarkus dev tools as the extension icon. It should be square, and any resolution greater than 220 pixels. Supported formats are png, jpeg, tiff, webp, and svg. Alternatively, if you set the social media preview on the extension’s source code repository, the tools will pick up that image.
9 | Codestart information
10 | Configuration prefix

And here is the final version of the file included in the runtime JAR augmented with other information collected by the Quarkus Maven plugin:

    name: "Quarkus REST (formerly RESTEasy Reactive)"
    artifact: "io.quarkus:quarkus-rest:999-SNAPSHOT"
    description: "A Jakarta REST implementation utilizing build time processing and Vert.x.\
      \ This extension is not compatible with the quarkus-resteasy extension, or any of\
      \ the extensions that depend on it." (1)
    metadata:
      short-name: "rest"
      keywords:
      - "jaxrs"
      - "web"
      - "rest"
      categories:
      - "web"
      - "reactive"
      status: "stable"
      guide: "https://quarkus.io/guides/rest"
      codestart:
        name: "rest"
        languages:
        - "java"
        - "kotlin"
        - "scala"
        artifact: "io.quarkus:quarkus-project-core-extension-codestarts::jar:999-SNAPSHOT"
      config:
      - "quarkus.rest."
      built-with-quarkus-core: "3.8.5" (2)
      requires-quarkus-core: "[3.8,)" (3)
      minimum-java-version: "17" (4)
      capabilities: (5)
        provides:
        - "io.quarkus.rest"
        - "io.quarkus.resteasy.reactive"
      extension-dependencies: (6)
      - "io.quarkus:quarkus-rest-common"
      - "io.quarkus:quarkus-mutiny"
      - "io.quarkus:quarkus-smallrye-context-propagation"
      - "io.quarkus:quarkus-vertx"
      - "io.quarkus:quarkus-arc"
      - "io.quarkus:quarkus-netty"
      - "io.quarkus:quarkus-vertx-http"
      - "io.quarkus:quarkus-core"
      - "io.quarkus:quarkus-jsonp"
    scm-url: "https://github.com/quarkusio/quarkus" (7)
    sponsor: A Sponsoring Organisation (8)

1 | Description that can be displayed to users. In this case, the description was copied from the `pom.xml` of the extension module but it could also be provided in the template file.
2 | Quarkus version the extension was built with
3 | The Quarkus version range this extension requires. Optional, and will be set automatically by using the `built-with-quarkus-core` as the minimum range.
4 | The minimum Java version required for this extension to run. Will be generated based on the `maven.compiler.release` used in the build.
5 | Capabilities this extension provides
6 | Direct dependencies on other extensions
7 | The source code repository of this extension. Optional, and will often be set automatically by using the `<scm>` information in the pom. In GitHub Actions builds, it will be inferred from the CI environment. For other GitHub repositories, it can be controlled by setting a `GITHUB_REPOSITORY` environment variable.
8 | The sponsor(s) of this extension. Optional, and will sometimes be determined automatically from commit history.

## META-INF/quarkus-extension.properties

Every runtime extension artifact must include this file. This file is read by the Quarkus bootstrap mechanism and is meant to contain only the information that is relevant for building or bootstrapping an applications. This file is typically generated by the corresponding Quarkus Maven or Gradle plugin when the extension project is built and shouldn’t be edited manually. The following properties may appear in this file:

Name | Presence | Description
--- | --- | ---
`deployment-artifact` | Required | Points to the corresponding extension deployment artifact in the `groupId:artifactId[:classifier:type]:version` format
`parent-first-artifacts` | Optional | Comma-separated list of artifact keys (`groupId:artifactId:classifier:type`) that are to be loaded in a parent first manner. This can be used to work around issues where a given class needs to be loaded by the system ClassLoader.
`runner-parent-first-artifacts` | Optional | Comma-separated list of artifact keys that are to be loaded in a parent first manner in addition to those configured with `parent-first-artifacts` when an application is launched from a production binary package. This can be used to work around issues where a given class needs to be loaded by the system ClassLoader.
`excluded-artifacts` | Optional | Comma-separated list of artifact keys that will never be loaded by the class loader, and will not be packed into the final application.
`lesser-priority-artifacts` | Optional | Comma-separated list of artifact keys that will only be used to load a class or resource if no other artifact containing that class or resource exists. This is used in order to control the order of artifacts when multiple contain the same classes.
`removed-resources.*` | Optional | Resources that should be removed/hidden from dependencies. This allows for classes and other resources to be removed from dependencies, so they are not accessible to the application. This is a map of artifact key to a comma-separated list of resources to be removed. When running in dev and test mode these resources are hidden from the ClassLoader, when running in production mode these files are removed from the jars that contain them. Note that if you want to remove a class you need to specify the class file name. e.g. to remove com.acme.Foo you would specify com/acme/Foo.class.
`provides-capabilities` | Optional | List of capabilities this extension provides
`requires-capabilities` | Optional | List of capabilities this extension requires to be provided by other Quarkus extensions
`conditional-dependencies` | Optional | List of conditional dependencies this extension declares
`dependency-condition` | Optional | Dependency condition that has to be satisfied for a conditional dependency on this extension to be activated
`dev-mode.jvm-option.std.<option-name>=<option-value>` | Optional | Standard Java command line option that should be added to command line launching an application in dev mode
`dev-mode.jvm-option.xx.<option-name>=<option-value>` | Optional | `-XX:` Java command line option that should be added to command line launching an application in dev mode
`dev-mode.lock.jvm-options` | Optional | A comma-separated list of standard Java command line options that should not be overridden by values that are pre-configured by the Quarkus Maven and Gradle plugins by default
`dev-mode.lock.xx-jvm-options` | Optional | A comma-separated list of `-XX:` Java command line options that should not be overridden by values that are pre-configured by the Quarkus Maven and Gradle plugins by default

## META-INF/quarkus-config-roots.list

This file may appear in a runtime extension artifact as well as in a deployment one. This file must not be edited manually, it is generated as part of the extension project build process and contains a list of Java class names that are annotated with `io.quarkus.runtime.annotations.ConfigRoot` an extension provides.

## META-INF/quarkus-javadoc.properties

Same as `quarkus-config-roots.list`, this file may appear in a runtime extension artifact as well in a deployment one. It is generated as part of the extension project build process from the descriptions of configuration options available in the classes annotated with `io.quarkus.runtime.annotations.ConfigRoot` and is not supported to be edited manually.

## META-INF/quarkus-build-steps.list

This file may appear in a deployment extension artifact. It contains a list of classes that implement Quarkus build steps (methods annotated with `io.quarkus.deployment.annotations.BuildStep`). This file is generated as part of the extension project build process and must not be edited manually.

## Quarkus Extension Maven Plugin

The `quarkus-extension-maven-plugin` is configured in the runtime module of a Quarkus extension Maven project and serves the following purposes:

- validate extension metadata configuration;

- generate extension metadata;

- check whether extension dependencies conform to the Quarkus extension dependency model.

### Dev mode JVM options

An extension may pre-configure certain Java command line options that should be added to the command line launching an application in Dev mode. Here is how such options can be configured in the `quarkus-extension-maven-plugin` configuration:

                <plugin>
                    <groupId>io.quarkus</groupId>
                    <artifactId>quarkus-extension-maven-plugin</artifactId>
                    <version>${quarkus.version}</version>
                    <executions>
                        <execution>
                            <phase>compile</phase>
                            <goals>
                                <goal>extension-descriptor</goal>
                            </goals>
                            <configuration>
                                <devMode>
                                    <jvmOptions>
                                        <add-modules>jdk.incubator.vector</add-modules>
                                        <enable-preview/>
                                        <enable-native-access>ALL-UNNAMED</enable-native-access>
                                    </jvmOptions>
                                    <xxJvmOptions>
                                        <UseThreadPriorities>false</UseThreadPriorities>
                                    </xxJvmOptions>
                                    <lockJvmOptions>agentlib:jdwp</lockJvmOptions>
                                    <lockXxJvmOptions>TieredStopAtLevel</lockXxJvmOptions>
                                </devMode>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

The `extension-descriptor` goal will generate `META-INF/quarkus-extension.properties` with the corresponding properties. And once an application that has a dependency on this extension is launched in Dev mode, the logs will look like

    [DEBUG] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] (main) Adding JVM options from org.acme:quarkus-blue::jar
    [DEBUG] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] (main)   enable-native-access: [ALL-UNNAMED]
    [DEBUG] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] (main)   add-modules: [jdk.incubator.vector]
    [DEBUG] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] (main)   enable-preview: []
    [DEBUG] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] (main)   UseThreadPriorities: [false]
    [DEBUG] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] (main) org.acme:quarkus-blue::jar locks JVM options [TieredStopAtLevel, agentlib:jdwp]
    [INFO] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] Extension org.acme:quarkus-blue enables the C2 compiler which is disabled by default in Dev mode for optimal performance.
    [INFO] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] Extension org.acme:quarkus-blue disables the Debug mode for optimal performance. Debugging can still be enabled in the Quarkus plugin configuration or with -Ddebug on the command line.
    [DEBUG] [io.quarkus.deployment.dev.DevModeCommandLineBuilder] (main) Executable jar: /home/<username>/app/target/acme-app-dev.jar
    [DEBUG] Launching JVM with command line: /home/<username>/jdk/bin/java -Dquarkus-internal.serialized-app-model.path=/home/<username>/app/target/quarkus/bootstrap/dev-app-model.dat -javaagent:/home/<username>/.m2/repository/io/quarkus/quarkus-class-change-agent/{quarkus-verion}/quarkus-class-change-agent-{quarkus-version}.jar --enable-native-access=ALL-UNNAMED --add-modules=jdk.incubator.vector --enable-preview -XX:-UseThreadPriorities -Djava.util.logging.manager=org.jboss.logmanager.LogManager -jar /home/<username>/app/target/acme-app-dev.jar

Note, there are a couple `INFO` messages informing the user that the values for certain options Quarkus uses by default in Dev mode were overridden by the extension preferences. Specifically, the C2 compiler was re-enabled and the debug mode was disabled. A user can still choose to enable the debug agent and disable the C2 compilter if necessary by explicitly setting the corresponding Quarkus Maven or Gradle plugin parameter values.