How to work around the @SupportedMethod problem?

The principle is:

  • Compile against Jira 8.13,
  • Add the @SupportedMethods in a library that you build yourself, which you set as ‘provided’ (the solution of @adam.labus on Jira 9.0 has a release candidate! - #45 by adam.labus )
  • Import that library and specify resolution:=optional in your pom.xml,
  • Ensure that classes using this annotation are never loaded in your Jira 8 plugin, otherwise you get a ClassNotFoundError. To do this, define a Webwork action specifically for Jira 9, which uses @SupportedMethods and inherits all your normal actions from the parent class (The implementation below is by @LaurentNonnenmacher ),
  • Only activate this Webwork module when Jira 9 is running.

Here’s our specific Jira 9.0 action, which inherits from the “normal” action:

package com.playsql.requirementyogijira.web;

import com.atlassian.jira.security.request.RequestMethod;
import com.atlassian.jira.security.request.SupportedMethods; // Don't import it from Jira 9, see below.

@SupportedMethods(RequestMethod.GET)
public class RYConfigureRelationshipsAction9 extends RYConfigureRelationshipsAction {

    @SupportedMethods({RequestMethod.GET, RequestMethod.POST})
    @Override
    public String doDefault() {
        return super.doDefault(); // So, just reuse the actions of the parent class.
    }
}

So you need a @SupportedMethods annotation, define it in a module:


and add the module to your pom.xml:

    <dependencies>
        <dependency>
            <!-- For Jira 8/9 compatibility-->
            <groupId>com.requirementyogi.plugins</groupId>
            <artifactId>workarounds-for-atlassian-problems</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.jira</groupId>
            <artifactId>jira-api</artifactId>
            <version>8.13.0</version> <!-- No need to depend on Jira 9! -->
            <scope>provided</scope>
        </dependency>

Don’t forget the Import-Package section in your atlassian-plugin.xml:


    <build>
        <plugins>
            <plugin>
                <groupId>com.atlassian.maven.plugins</groupId>
                <artifactId>amps-maven-plugin</artifactId>
                <version>${amps.version}</version>
                <extensions>true</extensions>
                <configuration>
                    <product>jira</product>
                    <productVersion>${jira.version}</productVersion>
                    <productDataVersion>${jira.version}</productDataVersion>
                    <applications>
                        <application>
                            <applicationKey>jira-software</applicationKey>
                            <version>${jira.version}</version>
                        </application>
                    </applications>
                    <ajpPort>5013</ajpPort>
                    <jvmDebugPort>5008</jvmDebugPort>
                    <jvmArgs>-Xmx1500m -Xms700m</jvmArgs>
                    <installPlugin>false</installPlugin>
                    <skipTests>${skipTests}</skipTests>
                    <instructions>
                        <Import-Package>
                            com.atlassian.jira;version="0.0.0",
                            com.atlassian.jira*;resolution:=optional;version="0.0.0", <!-- THIS is important, it's an OPTIONAL import -->
                            ...

Then, declare TWO webworks in your atlassian-plugin.xml:

<webwork1 key="ry-webwork-8" name="Requirement Yogi web pages for Jira 7 and 8" class="java.lang.Object" state="disabled">
        <action name="com.playsql.requirementyogijira.web.RYConfigureRelationshipsAction" alias="ry-configure-relationships" roles-required="admin">
            <view name="error">/templates/admin/ry-configure-relationships.vm</view>
            <view name="input">/templates/admin/ry-configure-relationships.vm</view>
        </action>
    </actions>
</webwork1>

<webwork1 key="ry-webwork-9" name="Requirement Yogi web pages for Jira 9 and above" class="java.lang.Object" state="disabled">
    <actions>
        <action name="com.playsql.requirementyogijira.web.RYConfigureRelationshipsAction9" alias="ry-configure-relationships" roles-required="admin">
            <view name="error">/templates/admin/ry-configure-relationships.vm</view>
            <view name="input">/templates/admin/ry-configure-relationships.vm</view>
        </action>
    </actions>
</webwork1>

And use this class to activates/deactivates the correct webwork action depending on the version of Jira:

package com.playsql.requirementyogijira.managers;

import com.atlassian.plugin.PluginController;
import com.atlassian.sal.api.ApplicationProperties;
import com.playsql.utils.SemVer;
import org.springframework.beans.factory.InitializingBean;

/**
 * This component handle which module to enable.
 *
 * Modules are located in atlassian-plugin.xml
 */
public class JiraVersionManager implements InitializingBean {

    private final PluginController pluginController;
    private final ApplicationProperties applicationProperties;

    public JiraVersionManager(PluginController pluginController,
                              ApplicationProperties applicationProperties) {

        this.pluginController = pluginController;
        this.applicationProperties = applicationProperties;
    }

    @Override
    public void afterPropertiesSet() {
        String jiraVersionString = applicationProperties.getVersion();
        SemVer jiraVersion = SemVer.parse(jiraVersionString);
        if (SemVer.compare(jiraVersion, SemVer.parse("9.0")) > 0) {
            pluginController.enablePluginModule("com.playsql.requirementyogijira:ry-webwork-9");
            pluginController.disablePluginModule("com.playsql.requirementyogijira:ry-webwork-8");
        } else {
            pluginController.enablePluginModule("com.playsql.requirementyogijira:ry-webwork-8");
            pluginController.disablePluginModule("com.playsql.requirementyogijira:ry-webwork-9");
        }
    }
}
4 Likes