Scroll Word Exporter Java API in Confluence Plugin
Asked by John Reese:

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.


Answers:
author: Matthias Gaiser _K15t_
body: Hi [@John Reese](/t5/user/viewprofilepage/user-id/4620367)

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.

comments: author: John Reese
body: 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!


author: Matthias Gaiser _K15t_
body: Thank you for sharing some more context, [@John Reese](/t5/user/viewprofilepage/user-id/4620367).

**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](https://developer.atlassian.com/server/confluence/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](https://developer.atlassian.com/server/confluence/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](https://developer.atlassian.com/server/confluence/spring-ioc-in-confluence/).

You could also do some [Confluence tutorials](https://developer.atlassian.com/server/framework/atlassian-sdk/product-specific-tutorials/#confluence-server) to learn more about accessing Confluence and the Scroll Exporter API.


author: John Reese
body: Hello [@Matthias Gaiser _K15t_](/t5/user/viewprofilepage/user-id/853318) 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


author: Matthias Gaiser _K15t_
body: [@John Reese](/t5/user/viewprofilepage/user-id/4620367) - 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";
   }
}
```


author: John Reese
body: Hello again [@Matthias Gaiser _K15t_](/t5/user/viewprofilepage/user-id/853318)

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


author: Matthias Gaiser _K15t_
body: 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.


author: John Reese
body: 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


Tags: api

app

confluence-server

k15t

scroll-word-exporter

server