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

This widget could not be displayed.

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.

Daniel Wester Community Champion Sep 21, 2017

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

This widget could not be displayed.
Daniel Wester Community Champion Aug 06, 2013
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.
This widget could not be displayed.

@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 Sign up to answer
Atlassian Summit 2018

Meet the community IRL

Atlassian Summit is an excellent opportunity for in-person support, training, and networking.

Learn more
Community showcase
Posted Wednesday in New to Jira

Are you planning to trial, or are currently trialling Jira Software? - We want to talk to you!

Hello! I'm Rayen, a product manager at Atlassian. My team and I are working hard to improve the trial experience for Jira Software Cloud. We are interested in   talking to 20 people planning t...

158 views 2 0
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