Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Scroll Word Exporter Java API in Confluence Plugin

John Reese November 2, 2021 edited

Hello everyone, i'm posting here and on kt15 forum looking for help. Got stuck while trying to implement the API

Maybe someone can help me here, i appreciate any help that i can get

Been using this link to set it up https://bitbucket.org/K15t/scroll-exporter-api/src/master/ and now when trying to export through the API this happens.

java.lang.NullPointerException
ScrollApi.exportWithDescendantPages(ScrollApi.java:19);

And at line 19:

WordExportRequest exportRequest = wordExportService.createExportRequest(rootPageId);

I already added every dependency to my confluence plugin.

Anybody knows how to do this properly? What am i missing? Trying to automate exports through the Java API, the REST API works fine.

1 answer

1 vote
Matthias Gaiser _K15t_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 2, 2021

Hi @John Reese

welcome to the Atlassian community.

Based on the information you‘ve shared, it looks like the variable wordExportService is null.

Can you check how you’re initializing it? If the ScrollApi class is a SpringBean, the easiest way would be to add the annotations @Autowired @ComponentImport.

Does that help? If not, please share more context how you‘re initializing the wordExportService.

Cheers,
Matthias.

John Reese November 2, 2021 edited

Hello and thank you!

Here it is 

import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.k15t.scroll.exporter.api.word.*;
import org.springframework.beans.factory.annotation.Autowired;

@Autowired @ComponentImport
private WordExportService wordExportService;
@Autowired @ComponentImport private WordTemplateService wordTemplateService;

So it's not really being initialized, i'm not even sure how to initialize it.

What do you mean by "Add annotations" should i add those annotations to the ScrollApi class?

Also no, my class is not a SpringBean, how do i make it a SpringBean? I'll look into it

Thank you!

Matthias Gaiser _K15t_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 2, 2021

Thank you for sharing some more context, @John Reese.

Short answer
I recommend to let Confluence instantiate your class via Spring. You usually annotate your class with @Component or @Named and Spring will then autowire the dependencies accordingly.

It could somehow look like these lines:

import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.k15t.scroll.exporter.api.word.*;
import org.springframework.beans.factory.annotation.Autowired;


@Component
public class MyClass {
@Autowired @ComponentImport private WordExportService wordExportService;
@Autowired @ComponentImport private WordTemplateService wordTemplateService;

public void exportWordFile() {
...
WordExportRequest exportRequest = wordExportService.createExportRequest(rootPageId);
...
}
}

Long answer
In order to get a deeper understanding, I recommend to read some background information about writing Confluence plugins which probably explain the concept better than I can. This page also links to a page for accessing Confluence Components from Plugin Modules. Accessing the Scroll API works analogue to the techniques described there for Confluence classes.
There's also another article with some more background information on Spring in Confluence.

You could also do some Confluence tutorials to learn more about accessing Confluence and the Scroll Exporter API.

John Reese November 3, 2021

Hello @Matthias Gaiser _K15t_ thanks for the reply

Thank your for the resources, did some of the tutorials and was able to add another functionality, however when doing the API calls i got stuck.

This is how it looks like now

import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.k15t.scroll.exporter.api.word.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@Component
public class ScrollApi {
@Autowired @ComponentImport private WordExportService wordExportService;
@Autowired @ComponentImport private WordTemplateService wordTemplateService;

public void exportWithDescendantPages(long rootPageId) throws IOException {
WordExportRequest exportRequest = wordExportService.createExportRequest(rootPageId);
WordExportResult exportResult = wordExportService.export(exportRequest);
}
}

I used @Component from org.springframework.stereotype.Component

And got the same result, null pointer exception

From my plugin class it's called like this

public class PluginTest extends ConfluenceActionSupport implements PageAware {

...
...

public String execute() throws Exception{
...
ScrollApi scrollApi = new ScrollApi();
scrollApi.exportWithDescendantPages(page);
...
return "success";
}
}

Is it being called correctly? Or is there another way?

I also tried the @Named annotation but couldn't find it.

Once again thank you very much for your help

Matthias Gaiser _K15t_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 3, 2021

@John Reese - thanks for sharing your PluginTest snippet. I think, there's what you need to fix. You've declared your ScrollApi class as a Component which is fine, but when you're accessing it in the PluginTest class, you're simply creating an instance yourself, but you should instead let Spring create the instance for you.

Your PluginTest class should then look like this:

public class PluginTest extends ConfluenceActionSupport implements PageAware {
@Autowired private ScrollApi scrollApi;

...

public String execute() throws Exception{
...
scrollApi.exportWithDescendantPages(page);
...
return "success";
}
}
Like • John Reese likes this
John Reese November 3, 2021 edited

Hello again @Matthias Gaiser _K15t_ 

I added the @Autowired annotation and my new button breaks.

With the @Autowired annotation after I click on my button it redirects me to a "Not Found Page" instead of the "Oops page", not sure what's missing here

I tried both

@Autowired @ComponentImport private ScrollApi scrollApi;

And

@Autowired private ScrollApi scrollApi;

Without the annotations the "Oops page" is shown with the exception once again.

Thank you for your help, i really appreciate it

Matthias Gaiser _K15t_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 4, 2021

The "Not Found Page" sounds to me like there's a general problem why you're page can't be initialized/loaded. Have you checked your confluence log file for more details?

The problem probably appears when you're app is loaded, so you might want to try disable/enable your app to see the problem in the logs.

John Reese November 4, 2021

Hello and thanks for the advice

Logs when clicking the new plugin button:

ERROR [http-nio-1990-exec-4] [atlassian.confluence.servlet.ConfluenceServletDispatcher] serviceAction There is no Action mapped for namespace /plugins/plugintest and action name plugin-test

Unfortunately that's it, and my action is mapped properly, because if the annotation @Autowired is removed from my PluginTest class it goes back to square one, throws the null pointer exception.

I didn't think of the disable/enable, so thanks for that.  Here it is:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.plugin.PluginTest': Unsatisfied dependency expressed through field 'scrollApi'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.plugin.scrollApi' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

It says expected at least 1 bean which qualifies as autowire candidate. And i have the autowire annotation on the ScrollApi class

ScrollApi

@Component
public class ScrollApi {

@Autowired @ComponentImport private WordExportService wordExportService;
@Autowired @ComponentImport private WordTemplateService wordTemplateService
...
}

PluginTest

public class PluginTest extends ConfluenceActionSupport implements PageAware {

@Autowired private ScrollApi scrollApi;
...
}

At least it's a different error now, i'll look into it

Once again, i really appreciate your help so far 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events