Developer
Get Support
Sign in
Get Support
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Last updated Oct 9, 2025

Transformed to transformerless plugin conversion

Transformerless plugins are preferable because:

  1. They start in a consistent manner across products & versions
  2. Without needing to be transformed they install & start faster
  3. The plugin system transformation has obscure, but frustrating bugs

AMPS 9.10 and above can perform the below steps automatically and more reliably via the transform goal. For a plugin targeting Confluence, for example, you can run:

1
2
mvn confluence:run confluence:stop confluence:transform -Dwait=false

0. Check your plugin is transformed

There are two ways to confirm:

a. via AMPS config

Look for the <configuration> block for the amps-maven-plugin (or jira-maven-plugin, confluence-, etc.) in your pom.xml file.

If under <instructions> it has both <Atlassian-Plugin-Key> and <spring-context> defined, it will not be transformed, thus it's a "transformerless" plugin.

e.g. This is a transformerless plugin

1
2
<plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-confluence-plugin</artifactId>
    <version>${amps.version}</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Atlassian-Plugin-Key>com.example.plugin.key</Atlassian-Plugin-Key>
            <Spring-Context>*</Spring-Context>
        </instructions>
    </configuration>
</plugin>

b. via cached directory

Transformed plugins are stored under the home directory. If you see your plugin jar there then it's a transformed plugin.

The directories for each product:

  • Bamboo: <bamboo_home>/caches/plugins/transformed-plugins/
  • Bitbucket: <bitbucket_home>/plugins/.osgi-cache/transformed-plugins
  • Confluence: <confluence_home>/plugins-osgi-cache/transformed-plugins
  • Crowd: <crowd_home>/caches/transformed-plugins
  • Jira: <jira_home>/plugins/.osgi-plugins/transformed-plugins

When running your plugin with AMPS it would be e.g. target/jira/home/plugins/.osgi-plugins/transformed-plugins

1. Copy the generated Spring XML files

  1. Start your plugin in a running product and grab the transformed .jar file.
  2. Extract the transformed .jar file
  3. Copy the spring XML files into the src/main/resources/META-INF/spring folder

2. Remove <component, <component-import, & <module-type plugin modules

Remove all <component, <component-import, & <module-type plugin modules from the atlassian-plugin.xml.

These are now defined in the Spring XML files.

3. Add bundle instructions to the POM

If the atlassian-plugin.xml file has a <bundle-instructions> block, move the contents to the pom.xml under the AMPS plugin, <configuration, <instructions block.

Then add an Import-Package entry for com.atlassian.plugin.osgi.bridge.external, as well as a wildcard optional import.

If your atlassian-plugin.xml references product-provided classes that are not also used in Java code, also add an import for their packages.

e.g. given an atlassian-plugin.xml file like:

1
2
<atlassian-plugin>
    <plugin-info>
    <description>${project.description}</description>
    <version>${project.version}</version>
    <bundle-instructions>
        <Import-Package>com.mylibrary</Import-Package>
    </bundle-instructions>
    </plugin-info>

    <web-item key="mysection" section="system.admin/administration">
        <link>/admin/mysection/endpoint</link>
        <condition class="com.atlassian.some.package.condition.PrivilegedCondition"/>
    </web-item>

would have <Import-Package>com.mylibrary</Import-Package> moved to the pom.xml with the following additions.

1
2
<plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-confluence-plugin</artifactId>
    <version>${amps.version}</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Import-Package>
                com.mylibrary,
                com.atlassian.plugin.osgi.bridge.external,
                com.atlassian.some.package.condition,
                *;resolution:=optional
            </Import-Package>
        </instructions>
    </configuration>
</plugin>

4. Define the Atlassian-Plugin-Key & Spring-Context instructions

These tell the plugin system that the plugin does not need to be transformed.

e.g.

1
2
<plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-confluence-plugin</artifactId>
    <version>${amps.version}</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Atlassian-Plugin-Key>com.example.plugin.key</Atlassian-Plugin-Key>
            <Spring-Context>*</Spring-Context>
        </instructions>
    </configuration>
</plugin>

5. Test your plugin

Check that it starts, is enabled, and passes all tests

6. [Optional] Use modern Spring wiring methods

Spring XML is powerful, but Spring Java configuration allows for attaching a debugger, programmatic flexibility, and the same powerfulness which is why we recommend it.

Alternately; Spring Scanner isn't as powerful, although it handles all the basic cases, and you may already be using it.

In both cases it's possible you may need to add Maven dependencies that were not declared before.

Rate this page: