No qualifying bean of type 'com.atlassian.webresource.api.assembler.PageBuilderService' available
Asked by Ill?s ?kos:

Hi all,

I was trying to do the first helloworld macro tutorial for Confluence from the Atlassian developer website ([Create a Confluence 'Hello World' macro (atlassian.com)](https://developer.atlassian.com/server/framework/atlassian-sdk/create-a-confluence-hello-world-macro/#create-the-plugin-skeleton)) and it seems like the atlassian spring scanner can't find the PageBuilderService class to import it. I'm new to Confluence plugin development so I don't know if this is a spring scanner problem or the class is deprecated.

If someone has another way of accessing the web resources that is also fine, the point here is not that I can't do the tutorial, but the fact I don't know why it doesn't work, so if you know the answer please give a detailed one.

Of course I added the appropriate plugin and dependencies to the pom.xml as shown in the spring scanner README ([atlassian / atlassian-spring-scanner / README.md --- Bitbucket](https://bitbucket.org/atlassian/atlassian-spring-scanner/src/2.1.x/README.md)) and modified the plugin-context.xml.

Thank you,  
Ill?s ?kos

Here are the logs:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'tutorial.macro.helloworld': Unsatisfied dependency expressed through constructor parameter 0; nested  
exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atlassian.webresource.api.assembler.PageBuilderService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport("")}  

Here is my hellowrold.java:  

```
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.webresource.api.assembler.PageBuilderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
```

```
@Component
public class helloworld implements Macro {
private final PageBuilderService pageBuilderService;

@Autowired
 public helloworld(@ComponentImport PageBuilderService pageBuilderService) {
this.pageBuilderService = pageBuilderService;
}

public String execute(Map<String, String> map, String s, ConversionContext conversionContext) throws MacroExecutionException {
pageBuilderService.assembler().resources().requireWebResource("tutorial.tutorial:tutorial-resources");
...
```


Answers:
author: Ill?s ?kos
body: Hi all, I found a not so satisfying solution in the means, that I don't really know which dependency solved my issue. My solution was to copy the pom.xml of a working confluence plugin into my own. As it turns out the Atlassian spring scanner was the one not working properly. I hope this is going to be helpful for some with the same issue. If somebody knows exactly which dependency fixed it, please tell me.

Here is my new pom.xml (only dependencies):  

```
<repositories>
    <repository>
        <id>atlassian2</id>
        <name>Atlassian2 Repository</name>
        <url>https://maven.atlassian.com/repository/public</url>
    </repository>

</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>atlassian2</id>
        <name>Atlassian2 Repository</name>
        <url>https://maven.atlassian.com/repository/public</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.atlassian.struts2</groupId>
            <artifactId>struts-support</artifactId>
            <version>1.2.2</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.atlassian.confluence</groupId>
        <artifactId>confluence</artifactId>
        <version>${confluence.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.atlassian.plugin</groupId>
        <artifactId>atlassian-spring-scanner-annotation</artifactId>
        <version>${atlassian.spring.scanner.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
        <scope>provided</scope>
    </dependency>

    <!-- provides lombok annotations -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.2</version>
        <scope>provided</scope>
    </dependency>
    <!-- provides @Component annotations -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>2.5.7-atlassian-1</version>
        <scope>provided</scope>
    </dependency>
    <!-- provides @JsonDeserialize annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.10.8</version>
        <scope>compile</scope>
    </dependency>

    <!-- WIRED TEST RUNNER DEPENDENCIES -->
    <dependency>
        <groupId>com.atlassian.plugins</groupId>
        <artifactId>atlassian-plugins-osgi-testrunner</artifactId>
        <version>${plugin.testrunner.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>jsr311-api</artifactId>
        <version>1.1.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.2.2-atlassian-1</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>com.atlassian.maven.plugins</groupId>
            <artifactId>confluence-maven-plugin</artifactId>
            <version>${amps.version}</version>
            <extensions>true</extensions>
            <configuration>
                <jvmArgs>-Xmx8192m</jvmArgs>
                <productVersion>${confluence.version}</productVersion>
                <productDataVersion>${confluence.data.version}</productDataVersion>
                <enableQuickReload>true</enableQuickReload>

                <!-- See here for an explanation of default instructions: -->
                <!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
                <instructions>
                    <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>

                    <!-- Add package import here -->
                    <Import-Package>
                        org.springframework.osgi.*;resolution:="optional",
                        org.eclipse.gemini.blueprint.*;resolution:="optional",
                        *
                    </Import-Package>

                    <!-- Ensure plugin is spring powered -->
                    <Spring-Context>*</Spring-Context>
                </instructions>
            </configuration>
        </plugin>
        <plugin>
            <groupId>com.atlassian.plugin</groupId>
            <artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
            <version>${atlassian.spring.scanner.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>atlassian-spring-scanner</goal>
                    </goals>
                    <phase>process-classes</phase>
                </execution>
            </executions>
            <configuration>
                <verbose>false</verbose>
            </configuration>
        </plugin>
    </plugins>
</build>

<properties>
    <confluence.version>8.5.3</confluence.version>
    <confluence.data.version>${confluence.version}</confluence.data.version>
    <amps.version>8.11.4</amps.version>
    <plugin.testrunner.version>2.0.2</plugin.testrunner.version>
    <spring.version>2.5.7-atlassian-1</spring.version>
    <atlassian.spring.scanner.version> 2.1.7 </atlassian.spring.scanner.version>
    <!-- This property ensures consistency between the key in atlassian-plugin.xml and the OSGi bundle's key. -->
    <atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.plugin.validation>VERBOSE</maven.plugin.validation>
</properties>
```

And here is my old(only dependencies):

```
<repositories>
    <repository>
        <id>atlassian2</id>
        <name>Atlassian2 Repository</name>
        <url>https://maven.atlassian.com/repository/public</url>
    </repository>

</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>atlassian2</id>
        <name>Atlassian2 Repository</name>
        <url>https://maven.atlassian.com/repository/public</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.atlassian.confluence</groupId>
        <artifactId>confluence</artifactId>
        <version>${confluence.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.atlassian.plugins</groupId>
        <artifactId>atlassian-plugins-osgi-javaconfig</artifactId>
        <version>${osgi.javaconfig.version}</version>
    </dependency>
    <!-- OSGi Java Config dependencies -->
    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.framework</artifactId>
        <version>4.0.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
        <scope>provided</scope>
    </dependency>

    <!-- WIRED TEST RUNNER DEPENDENCIES -->
    <dependency>
        <groupId>com.atlassian.plugins</groupId>
        <artifactId>atlassian-plugins-osgi-testrunner</artifactId>
        <version>${plugin.testrunner.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>jsr311-api</artifactId>
        <version>1.1.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.2.2-atlassian-1</version>
    </dependency>
    <dependency>
        <groupId>com.atlassian.plugin</groupId>
        <artifactId>atlassian-spring-scanner-annotation</artifactId>
        <version>${atlassian.spring.scanner.version}</version>
        <scope>provided</scope>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>com.atlassian.maven.plugins</groupId>
            <artifactId>confluence-maven-plugin</artifactId>
            <version>${amps.version}</version>
            <extensions>true</extensions>
            <configuration>
                <productVersion>${confluence.version}</productVersion>
                <productDataVersion>${confluence.data.version}</productDataVersion>
                <enableQuickReload>true</enableQuickReload>

                <!-- See here for an explanation of default instructions: -->
                <!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
                <instructions>
                    <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>

                    <!-- Add package to export here -->
                    <Export-Package>
                        com.aimotive.api,
                    </Export-Package>

                    <!-- Add package import here -->
                    <Import-Package>
                        org.springframework.osgi.*;resolution:="optional",
                        org.eclipse.gemini.blueprint.*;resolution:="optional",
                        com.atlassian.confluence.*;resolution:="optional",
                        *
                    </Import-Package>

                    <!-- Ensure plugin is spring powered -->
                    <Spring-Context>*</Spring-Context>
                </instructions>
            </configuration>
        </plugin>
        <plugin>
            <groupId>com.atlassian.plugin</groupId>
            <artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
            <version>${atlassian.spring.scanner.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>atlassian-spring-scanner</goal>
                    </goals>
                    <!-- process-classes seems to be skipped if you are using scala
                         so perhaps use prepare-package -->
                    <phase>process-classes</phase>
                </execution>
            </executions>
            <configuration>
                <!-- Enable this to get build-time logging of annotations atlassian-spring-scanner-maven-plugin has noticed -->
                <verbose>true</verbose>

                <!-- EXAMPLE EXAMPLE EXAMPLE :)
                     Demonstrates excluding packages from scanning, and scanning an example dependency jar.
                     Please see the docs below. -->

                <includeExclude>+com.atlassian.jira.plugins.issue.create.*</includeExclude>
                <scannedDependencies>
                    <dependency>
                        <groupId>com.atlassian.plugin</groupId>
                        <artifactId>atlassian-spring-scanner-test-example-external-jar</artifactId>
                    </dependency>
                </scannedDependencies>
            </configuration>
        </plugin>
    </plugins>
</build>

<properties>
    <confluence.version>8.5.1</confluence.version>
    <confluence.data.version>${confluence.version}</confluence.data.version>
    <amps.version>8.10.1</amps.version>
    <plugin.testrunner.version>2.0.2</plugin.testrunner.version>
    <osgi.javaconfig.version>0.5.2</osgi.javaconfig.version>
    <spring.version>6.1.6</spring.version>
    <atlassian.spring.scanner.version> 2.1.7 </atlassian.spring.scanner.version>
    <!-- This property ensures consistency between the key in atlassian-plugin.xml and the OSGi bundle's key. -->
    <atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
</properties>
```


Tags: app

atlassian

confluence-data-center

confluence-development

data-center

helloworld

macro

spring

tutorial