NoSuchBeanDefinitionException in Jira plugin when using Active Objects

Hi there,

I have been using the example [refapp plugin] (https://developer.atlassian.com/server/framework/atlassian-sdk/getting-started-with-active-objects/) since I am new to creating Jira Plugins…

I created a Jira plugin instead of refapp.
Then I get the following error at Step 6:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘com.example.mySampleAO.todo.TodoServlet’: Unsatisfied dep endency expressed through constructor argument with index 0 of type [com.atlassian.activeobjects.external.ActiveObjects]: No qualifying bean of type[com.atlassian.activeobjects.external.ActiveObjects] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.atlassian.activeobjects.external.ActiveObjects] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Could someone tell me what the reason for this error is? What is the right way of using annotations in the Jira plugin?

Looking forward for help…

You need to @ComponentImport on the ActiveObjects dependency and use a provided dependency:

<dependency>
   <groupId>com.atlassian.activeobjects</groupId>
   <artifactId>activeobjects-plugin</artifactId>
   <version>1.1.5</version>
   <scope>provided</scope>
</dependency>

See: Kitchen Duty Planning REST Resource ~ Planning Page | Plugin Development Tutorial for Atlassian JIRA® | Kitchen Duty Plugin by codeclou UG

Hi Clouless,
Sorry for the late reply. [And don’t know how to get all the code inside a code block below.]

I do have what you mentioned. Here is the code I have:

Todo.java:

@Preload
public interface Todo extends Entity
{

@NotNull
void setUser(User user);

@NotNull
User getUser();

String getDescription();

void setDescription(String description);

boolean isComplete();

void setComplete(boolean complete);

}

User.java:

@Preload
public interface User extends Entity
{
@NotNull
@Unique
String getName();
void setName(String name);
}

TodoServlet.java

@Named
public final class TodoServlet extends HttpServlet
{
@ComponentImport
private final TodoService todoService;
@ComponentImport
private final UserManager userManager;

`@Autowired`
public TodoServlet(TodoService todoService, UserManager userManager)
{
    this.todoService = checkNotNull(todoService);
    this.userManager = checkNotNull(userManager);
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
if (!enforceLoggedIn(req, res))
{
return;
}

    final PrintWriter w = res.getWriter();
    w.printf("<h1>Todos (%s)</h1>", userManager.getRemoteUser().getUsername());

    // the form to post more TODOs
    w.write("<form method=\"post\">");
    w.write("<input type=\"text\" name=\"task\" size=\"25\"/>");
    w.write("&nbsp;&nbsp;");
    w.write("<input type=\"submit\" name=\"submit\" value=\"Add\"/>");
    w.write("</form>");

    w.write("<ol>");

    for (Todo todo : todoService.all())
    {
        w.printf("<li><%2$s> %s </%2$s></li>", todo.getDescription(), todo.isComplete() ? "strike" : "strong");
    }

    w.write("</ol>");
    w.write("<script language='javascript'>document.forms[0].elements[0].focus();</script>");

    w.close();
}

`@Override`
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
    if (!enforceLoggedIn(req, res))
    {
        return;
    }

    final String description = req.getParameter("task");
    todoService.add(description);
    res.sendRedirect(req.getContextPath() + "/plugins/servlet/todo/list");
}

private boolean enforceLoggedIn(HttpServletRequest req, HttpServletResponse res) throws IOException
{
    if (userManager.getRemoteUser() == null)
    {
        res.sendRedirect(req.getContextPath() + "/plugins/servlet/login");
        return false;
    }
    return true;
}

}

TodoServiceImpl.java

@ExportAsService({TodoService.class})
@Named("TodoService")
public class TodoServiceImpl implements TodoService
{
@ComponentImport
private final ActiveObjects ao;
@ComponentImport
private final UserManager userManager;

`@Inject`
public TodoServiceImpl(ActiveObjects ao, UserManager userManager)
{
    this.ao = checkNotNull(ao);
    this.userManager = checkNotNull(userManager);
}

@Override
public Todo add(String description)
{
User user = getOrCreateUser(ao, currentUserName());
final Todo todo = ao.create(Todo.class, new DBParam(“USER_ID”, user.getID()));
todo.setDescription(description);
todo.setComplete(false);
todo.save();
return todo;
}

`@Override`
public List<Todo> all()
{
    User user = getOrCreateUser(ao, currentUserName());
    return newArrayList(ao.find(Todo.class, Query.select().where("USER_ID = ?", user.getID())));
}

private String currentUserName() {
    return userManager.getRemoteUser().getUsername();
}

private User getOrCreateUser(ActiveObjects ao, String userName)
{
    User[] users = ao.find(User.class, Query.select().where("NAME = ?", userName));
    if (users.length == 0) {
        return createUser(ao, userName);
    } else if (users.length == 1) {
        return users[0];
    } else {
        throw new IllegalStateException("There shouldn't be 2 users with the same username! " + userName);
    }
}

private User createUser(ActiveObjects ao, String userName)
{
    return ao.create(User.class, ImmutableMap.<String, Object>of("NAME", userName));
}

}

TodoService.java

@Transactional
public interface TodoService
{
Todo add(String description);

List<Todo> all();

}

The error I received is:
[INFO] [talledLocalContainer] Caused by: org.springframework.beans.factory.UnsatisfiedDependencyE
xception: Error creating bean with name ‘com…todo.TodoServlet’: Unsatisfie
d dependency expressed through constructor argument with index 0 of type [com…todo.TodoService]: No qualifying bean of type [com…todo.TodoService] f
ound for dependency: expected at least 1 bean which qualifies as autowire candidate for this depe
ndency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchB
eanDefinitionException: No qualifying bean of type [com…todo.TodoService]
found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dep
endency. Dependency annotations: {}

[INFO] [talledLocalContainer] Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionEx
ception: No qualifying bean of type [com…todo.TodoService] found for depen
dency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Depend
ency annotations: {}

Can you please tell me what is the dependency that I am missing here?

Hi,
seems all pretty right. Could be the src/main/resources/atlassian-plugin.xml
that is missing this:

<ao key="ao-module">
    <description>The module configuring the Active Objects service used by this plugin</description>
    <entity>....ao.Todo</entity>
</ao>

or your Spring Scanner setup is not correct. Maybe check this too:
https://bitbucket.org/atlassian/atlassian-spring-scanner/src/master/

At best open a support ticket at Atlassian or maybe an Atlassian Staff member can help you here.

Cheers,