Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Extend your Jira Server/Data Center app with ModuleType Part 2

Part 1

Change our app

Now we need to add support for modules to our calculator.

First uncomment the jira-core dependency in the pom.xml file.


Then add com.atlassian.plugin.osgi.bridge.external to Import-Package in the pom.xml file

<Import-Package>org.springframework.osgi.*;resolution:="optional", com.atlassian.plugin.osgi.bridge.external, org.eclipse.gemini.blueprint.*;resolution:="optional", *</Import-Package>

Next add our module descriptor.


public class OperationModuleDescriptor extends AbstractModuleDescriptor<Operation>
public OperationModuleDescriptor(final @ComponentImport ModuleFactory moduleFactory)

public Operation getModule()
return moduleFactory.createModule(moduleClassName, this);

As you can see we created this module descriptor as AbstractModuleDescriptor of the Operation interface type.

Next, we need to register our module descriptor.


public class BasicModuleTypeFactory extends
public BasicModuleTypeFactory(HostContainer hostContainer)
super(hostContainer, "calculatorOperation", OperationModuleDescriptor.class);

As you can see We registered our module descriptor under the calculatorOperation name.


Now apps can define calculatorOperation in their atlassian-plugin.xml file.

But let's also change our CalculatorService.

When we need to look for operations in modules of external apps.

I changed src/main/java/ru/matveev/alexey/atlassian/calculator/service/ to this one:

public class CalculatorService {
private final SumOperation sumOperation;
private final PluginAccessor pluginAccessor;
public CalculatorService(final @ComponentImport PluginAccessor pluginAccessor, SumOperation sumOperation) {
this.sumOperation = sumOperation;
this.pluginAccessor = pluginAccessor;

public int calculate(String operation, int val1, int val2) throws OperationNotFoundException {
if (operation.equals(sumOperation.getName())) {
return sumOperation.calculate(val1, val2);
Operation operationModule = this.getModuleForOperationName(operation);
if (operationModule != null) {
return operationModule.calculate(val1, val2);
throw new OperationNotFoundException(String.format("Operation %s not found", operation));

private Operation getModuleForOperationName(String operationName) {
List<OperationModuleDescriptor> operationModuleDescriptors =
for (OperationModuleDescriptor operationModuleDescriptor : operationModuleDescriptors)
if (operationName.equals(operationModuleDescriptor.getModule().getName())) {
return operationModuleDescriptor.getModule();
return null;

I added getModuleForOperationName which returns a reference to a module in an external app if the operation name we want to execute equals to the name of the operation provided by this module.

And then I added these lines to the calculate method:

Operation operationModule = this.getModuleForOperationName(operation);
if (operationModule != null) {
return operationModule.calculate(val1, val2);

First, we look for a module in another app which provides implementation of the operation we need and then we run the calculate method on the found module.

That is all with the calculator app. Now let's write an extension to our app.


I created an ordinary plugin from Atlassian SDK.

I added dependency to the jar file of the calculator app. I need it to use the Operation interface defined in the calculator app.


Then I created the minus operation.


public class MinusOperation implements Operation {
public String getName() {
return "minus";

public int calculate(int val1, int val2) {
return val1 - val2;

As you can see I implemented this class from the Operation interface and defined two methods: getName (returns the "minus" value) and calculate.

And now I can add calculatorOperation module to the atlassian-plugin.xml file.


 <calculatorOperation key="minus-operation"  class="ru.matveev.alexey.atlassian.operation.MinusOperation"/>

And that is it. Install this app to the same Jira instance where the Calculator app is installed.

Test extension app

I installed our two apps to the same Jira instance.

Screenshot 2020-09-06 at 21.07.34.png

And now I will execute our http://localhost:2990/jira/rest/calculator/1.0/calculate REST endpoint with the following request body:

{"operation": "minus", "value1": 1, "value2" : 3}

As you can see I am trying to use the minus operation from our calculator-extension app. And here is the result:

Screenshot 2020-09-06 at 20.56.35.png

And the result is -2 as expected. We did what we wanted. We added a new operation in an external app for our calculator app. Now other apps can extend our calculator with their own operations.

You can find the final code here.



Log in or Sign up to comment
Community showcase
Published in Apps & Integrations

🍻🍂Apptoberfest Update: Upcoming Virtual Events 🎉

Hello Community! I hope you've been enjoying the 🍂Apptoberfestivities🍂 (I know I have!) The event is heating up next week with a series of virtual events that we're calling the 🍻🍂Partner App ...

456 views 5 18
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you