How to bundle multiple modules in the same plugin?

Hello, right now I have multiple plugins where each provides a single small feature (like a custom field; a post-function, …), and I’m researching if I can bundle them into a single plugin to help me managing shared code between them. Would be nice to have something like the default JIRA Toolkit Plugin, which bundles 21 modules together (check the screenshot attached).

But I can’t find anything related in the documentation, seems like it’s a feature exclusive for JIRA Toolkit Plugin. Does anyone know if is it possible to do this? Or have a better suggestion on how to handle multiple plugins?

1 Like

I’ve forwarded your post to the Marketplace Vendor slack channel, as I’m really keen on learning this myself. I know it can be done (Tempo Timesheets has a “shared” bundle). It is also used to work around the max JAR file size for larger plugins by splitting code into multiple deliverables.

I’m sorry but I’m quite confused. You posted this in the “Jira Cloud” category and you also linked to a Jira Cloud documentation page. But I think your screenshot is actually from Jira Server?

If you are talking about adding modules to a Jira Server App please have a look here. You can add modules to your plugin using either the atlas-create-jira-plugin-module command or by manually adding the module to your atlassian-plugin.xml.

IIUC what he is trying to do is create a separate JAR with shared public components public=true (atlassian-plugin.xml) / @ExportasService (spring scanner) which are listed as modules in UPM and which can be consumed by multiple plugins he is creating using component-import (atlassian-plugin.xml) / @ComponentImport (spring scanner).

At least, that is how I interpreted this.

To give an example: if you download the latest version of Tempo Timesheets from the Atlassian Marketplace, you will actually get an OBR file, not a JAR file, of which the contents look like this:

32

As you can see, Tempo Timesheets actually consists of 7 jar files. The main jar file and 6 dependencies, some of which are also used by Tempo Planner.

But maybe I’m reading to much in this because I want to actually learn how to do this :joy:

Interesting. I’m not sure if that’s what @danilo.resende means because as far as I know the UPM simply lists all modules defined in the atlassian-plugin.xml (or defined via the Spring Scanner).

The mentioned Jira Toolkit Plugin also isn’t an OBR but a JAR… But let’s wait for @danilo.resende to elaborate. :slight_smile:

Yeah, I think I might be reading to much into this and overcomplicating it. Oh wel… the OBR thingy is pretty cool either way. Oh and you should switch to Spring Scanner instead of adding modules in the atlassian-plugin.xml!

1 Like

What’s that? Can you share more details about the slack channel?

It’s a slack channel for Marketplace Vendors where you can tap into the collective knowledge of the hive :honeybee: Anyway, you can signup here: https://signup.marketplace-vendor-resources.com. Please use a corporate email if possible (instead of gmail, outlook, etc).

3 Likes

The screenshot is from a Jira Cloud instance, the Jira Toolkit Plugin is installed there by default.

Thank you, so this can be is easily achieved in a Java plugin.

But do anyone knows if the same is possible in Javascript?

To build an OBR, I think you just need to have several in your pom.xml. Here’s the related section of our pom.xml:


    <build>
        <plugins>
            <plugin>
                <groupId>com.atlassian.maven.plugins</groupId>
                <artifactId>maven-amps-plugin</artifactId>
                <version>5.0.13</version>
                <extensions>true</extensions>
                <configuration>
                    <httpPort>1991</httpPort>
                    <contextPath>/confluence</contextPath>
                    <systemPropertyVariables>
                        <upm.pac.disable>true</upm.pac.disable>
                    </systemPropertyVariables>
                    <enableFastdev>false</enableFastdev>
                    
                    ...

                    <!--- HERE --->
                    <pluginDependencies>
                        <pluginDependency>
                            <groupId>com.playsql</groupId>
                            <artifactId>play-sql-export-addon</artifactId> <!-- That's a 15MB module for Excel import/exports -->
                        </pluginDependency>
                        <pluginDependency>
                            <groupId>com.playsql</groupId>
                            <artifactId>playsql-base-plugin</artifactId> <!-- That's a 'core' plugin that is also available separately on the Marketplace -->
                        </pluginDependency>
                    </pluginDependencies>
                </configuration>
            </plugin>

Gotchas:

  • After doing this, open your OBR and check the MANIFEST.MF file. I think there’s a place where it swaps the original name of your plugin with [the name]-parent, and that could disturb the Marketplace and make it believe it’s not the same plugin anymore.
  • The default JDBC request size in MySQL is 4MB, so customers will have to change the limits manually, and there are several little details that customers have to change to allow bigger plugins. Basically, they know how to do it, but bigger files means it slightly alters the ease of trying.
  • I notice that I also have the following section of code in my tag, I don’t remember what it was for, so don’t use it initially but it may help you if you stumble upon an issue:
<build>
<plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.8</version>
                <executions>
                    <execution>
                        <id>attach-bundle-artifact</id>
                        <phase>package</phase>
                        <goals>
                            <goal>attach-artifact</goal>
                        </goals>
                        <configuration>
                            <artifacts>
                                <artifact>
                                    <file>${project.build.directory}/${project.build.finalName}.jar</file>
                                    <type>jar</type>
                                </artifact>
                            </artifacts>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
1 Like

How about if these modules are not plugins? What I am trying to do is:

/pom.xml (parent)
    - core-module
        - pom.xml
    - api-module
        - pom.xml
    - main-plugin
        - pom.xml

main-plugin depends on the other two regular maven modules (not plugins).
With this, if I run atlas-package from the root module, it packages the plugin successfully. However, I have a problem with atlas-run, as it doesn’t seem to find the plugin in the main-plugin submodule.

Thoughts?

2 Likes

hi Atlassian experts!

How can the setup in vpelizza’s post above be achieved? I’d like to do the same.

?

1 Like

Were you able to achieve this? Or anyone else?

/pom.xml (parent)
    - core-module
        - pom.xml
    - api-module
        - pom.xml
    - main-plugin
        - pom.xml

I am also trying to create a multi maven module Confluence plugin and I am facing an issue where the @Component from core-module is not able to instantiate and be used in main-plugin module.

Any help on this will be greatly appreciated.
Thanks!