how to use same active object tables in two different plugin?

I have created a table through active object in one plugin. And i want to access the same active object table in another plugin.

What should i have in my plugin descriptor and classes ?

3 answers

1 accepted

Rephrasing Daniel:

  • AO Tables are sandboxed and can't be seen from other plugins;
  • The component that manages the table (the DAO) can be made visible to other plugins.

However, making the component public requires good programming skills. There probably are a thousand questions about that, but here's a summary:

  • In atlassian-plugin.xml,
    • Declare your <component/> as public=true (It's Spring technology),
    • Declare an <interface> tag inside your component.
  • In pom.xml
    • Declare an <Export-Package> tag to export the java class (It's OSGi technology),
    • The other plugin must declare the first one in <dependencies>, with <scope>provided</scope>
  • Good luck. There should be a "I've mastered an Export-Package declaration" badge on Answers ;)

Can you give me a simple example? Atlassian Spring Scanner compliant.

I would suggest moving this question over to community.developers.atlassian.com (lot's more developers there :) ).

But the basic gist is that you'll need to create another maven artifact that holds all of your interfaces.

Then in the add-on that has the service that you want to expose, implement that interface.

Then you'll need to annotate the class with

@ExportAsAService

Then in your pom.xml where you have the <Import-Package/> area - add:

<Export-Package>your package to the interface here</Export-Package>

 

Then in your add-on that imports the service, just do an @ComponentImport and you'll be in business.

These are not real plugins. Written just briefly so that I can understand it. Maybe someone can add to that or at least comment on it.

 

Plugin Test with AO

package com.test.confluence.plugins.ao.table;

import net.java.ao.Entity;
import net.java.ao.Preload;
import net.java.ao.schema.Table;

import java.util.Date;

@Preload
@Table("TEST_FIELD")
public interface TestAoTable extends Entity {

public String getFieldValue();
public void setFieldValue(String fieldValue);

public String getFieldName();
public void setFieldName(String fieldName);
}

AO TABLE

 

package com.test.confluence.plugins.ao;

import com.test.confluence.plugins.ao.model.FieldModel;
import java.util.List;

@ExportAsService
public interface TestAo {

FieldModel get(String field);
FieldListModel getList();
Boolean add(FieldModel model);
Boolean update(FieldModel model);
Boolean delete(FieldModel model);

}

 TestAo Interface

 

package com.test.confluence.plugins.serviceportal.ao.impl;

@Component
@ExportAsService
public class TestAoImpl implements TestAo {

private final ActiveObjects ao;
private final TransactionTemplate transactionTemplate;


@Autowired
public TestAoImpl(@ComponentImport final ActiveObjects ao,
@ComponentImport final TransactionTemplate transactionTemplate) {
this.ao = ao;
this.transactionTemplate = transactionTemplate;
}

@Override
public FieldModel get(String field) {
// ...
}

@Override
public FieldModel getList() {
// ...
}

@Override
public Boolean add(FieldModel model) {
// ...
}

@Override
public Boolean update(FieldModel model) {
// ...
}

@Override
public Boolean delete(FieldModel model) {
// ...
}
}

TestAo Implemantation

 

 <build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-amps-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<extractDependencies>false</extractDependencies>
<jvmDebugSuspend>${jvm.debug.suspend}</jvmDebugSuspend>
<instructions>
<Atlassian-Plugin-Key>${project.groupId}.${project.artifactId}</Atlassian-Plugin-Key>
<Spring-Context>*</Spring-Context>
<Export-Package>
com.test.confluence.plugins.ao.ao.*;resolution:="optional"
</Export-Package>
<Import-Package>
com.atlassian.confluence.*;resolution:="optional",
*;resolution:="optional"
</Import-Package>
</instructions>
<products>
<product>
<id>confluence</id>
<version>${confluence.version}</version>
<httpPort>${product.httpPort}</httpPort>
<contextPath>${product.contextPath}</contextPath>
</product>
</products>
</configuration>
</plugin>
...

</plugins>
</build>

Part of Test Plugin pom.xml 

 

 

Plugin Lorem

package com.lorem.confluence.plugins.macro;

@Component
public class LoremMacro implements Macro {

private final TestAo testAo;

@Autowired
public LoremMacro(@ComponentImport final TestAo testAo) {
this.testAo = testAo;
}


@Override
public BodyType getBodyType() {
return BodyType.NONE;
}


@Override
public OutputType getOutputType() {
return OutputType.INLINE;
}


@Override
public String execute(Map<String, String> parameters, String bodyContent, ConversionContext conversionContext)
throws MacroExecutionException {

Map<String, Object> data = MacroUtils.defaultVelocityContext();
FieldModel model = this.testAo.get("lorem");
data.put("lorem", model);

return VelocityUtils.getRenderedTemplate(MACRO_BODY_TEMPLATE, data);
}
}

LoremMacro with TestAoImpl

My Result :-)

Error rendering macro 'lorem-macro' : AOP configuration seems to be invalid: tried calling method [public abstract com.test.confluence.plugins.ao.table.TestAoTable[] com.test.confluence.plugins.ao.TestAo.getList(java.lang.String)] on target [com.test.confluence.plugins.ao.TestAoImpl@462abb3]; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring class

1 votes
Since the ao tables are sandboxed so that they're isolated on a per plugin basis - you'll need to make sure the <component/> declarations declare them as public="true" and then in the second plugin you'd need to use <component-import/> to pull them in.

@Daniel,

how the ao tables are exposed to other plugins?

Should i expose each table entity interface separately as component.

@Dipti Ranjan Behera

Add in the <component-import/> interface which is implemented by you <component/>

Suggest an answer

Log in or Join to answer
Community showcase
Sarah Schuster
Posted Jan 29, 2018 in Jira

What are common themes you've seen across successful & failed Jira Software implementations?

Hey everyone! My name is Sarah Schuster, and I'm a Customer Success Manager in Atlassian specializing in Jira Software Cloud. Over the next few weeks I will be posting discussion topics (8 total) to ...

3,119 views 13 19
Join discussion

Atlassian User Groups

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

Find a group

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

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you
Atlassian Team Tour

Join us on the Team Tour

We're bringing product updates and pro tips on teamwork to ten cities around the world.

Save your spot