import com.atlassian.jira.bc.issue.IssueService;
import com.atlassian.jira.bc.issue.search.SearchService;
import com.atlassian.jira.bc.project.ProjectService;
import com.atlassian.jira.config.ConstantsManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueInputParameters;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.issuetype.IssueType;
import com.atlassian.jira.issue.search.SearchException;
import com.atlassian.jira.issue.search.SearchResults;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.query.Query;
import com.atlassian.templaterenderer.TemplateRenderer;
import com.atlassian.jira.jql.builder.JqlClauseBuilder;
import com.atlassian.jira.jql.builder.JqlQueryBuilder;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.user.ApplicationUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class RunGrovyServlet extends HttpServlet {
private static final Logger log = LoggerFactory.getLogger(RunGrovyServlet.class);
private IssueService issueService;
private ProjectService projectService;
private SearchService searchService;
private TemplateRenderer templateRenderer;
private JiraAuthenticationContext authenticationContext;
private ConstantsManager constantsManager;
private static final String LIST_ISSUES_TEMPLATE = "/templates/list.vm";
private static final String NEW_ISSUE_TEMPLATE = "/templates/new.vm";
private static final String EDIT_ISSUE_TEMPLATE = "/templates/edit.vm";
public RunGrovyServlet(IssueService issueService, ProjectService projectService,
SearchService searchService,
TemplateRenderer templateRenderer,
JiraAuthenticationContext authenticationContext,
ConstantsManager constantsManager) {
this.issueService = issueService;
this.projectService = projectService;
this.searchService = searchService;
this.templateRenderer = templateRenderer;
this.authenticationContext = authenticationContext;
this.constantsManager = constantsManager;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String action = Optional.ofNullable(req.getParameter("actionType")).orElse("");
Map<String, Object> context = new HashMap<>();
resp.setContentType("text/html;charset=utf-8");
switch (action) {
case "new":
templateRenderer.render(NEW_ISSUE_TEMPLATE, context, resp.getWriter());
break;
case "edit":
IssueService.IssueResult issueResult = issueService.getIssue(authenticationContext.getLoggedInUser(),
req.getParameter("key"));
context.put("issue", issueResult.getIssue());
templateRenderer.render(EDIT_ISSUE_TEMPLATE, context, resp.getWriter());
break;
default:
List<Issue> issues = getIssues();
context.put("issues", issues);
templateRenderer.render(LIST_ISSUES_TEMPLATE, context, resp.getWriter());
}
}
private List<Issue> getIssues() {
ApplicationUser user = authenticationContext.getLoggedInUser();
JqlClauseBuilder jqlClauseBuilder = JqlQueryBuilder.newClauseBuilder();
Query query = jqlClauseBuilder.project("TEST").buildQuery();
PagerFilter pagerFilter = PagerFilter.getUnlimitedFilter();
try {
SearchResults<Issue> searchResults = searchService.search(user, query, pagerFilter);
return searchResults.getResults();
} catch (SearchException e) {
log.error("Error retrieving issues from Jira", e);
return Collections.emptyList();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String actionType = req.getParameter("actionType");
switch (actionType) {
case "edit":
handleIssueEdit(req, resp);
break;
case "new":
handleIssueCreation(req, resp);
break;
default:
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
private void handleIssueEdit(HttpServletRequest req, HttpServletResponse resp) throws IOException {
ApplicationUser user = authenticationContext.getLoggedInUser();
Map<String, Object> context = new HashMap<>();
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
issueInputParameters.setSummary(req.getParameter("summary"))
.setDescription(req.getParameter("description"));
MutableIssue issue = issueService.getIssue(user, req.getParameter("key")).getIssue();
IssueService.UpdateValidationResult result =
issueService.validateUpdate(user, issue.getId(), issueInputParameters);
if (result.getErrorCollection().hasAnyErrors()) {
context.put("issue", issue);
context.put("errors", result.getErrorCollection().getErrors());
resp.setContentType("text/html;charset=utf-8");
templateRenderer.render(EDIT_ISSUE_TEMPLATE, context, resp.getWriter());
} else {
issueService.update(user, result);
resp.sendRedirect("rungrovyscript");
}
}
private void handleIssueCreation(HttpServletRequest req, HttpServletResponse resp) throws IOException {
ApplicationUser user = authenticationContext.getLoggedInUser();
Map<String, Object> context = new HashMap<>();
Project project = projectService.getProjectByKey(user, "TEST").getProject();
if (project == null) {
context.put("errors", Collections.singletonList("Project doesn't exist"));
templateRenderer.render(LIST_ISSUES_TEMPLATE, context, resp.getWriter());
return;
}
IssueType taskIssueType = constantsManager.getAllIssueTypeObjects().stream().filter(
issueType -> issueType.getName().equalsIgnoreCase("task")).findFirst().orElse(null);
if(taskIssueType == null) {
context.put("errors", Collections.singletonList("Can't find Task issue type"));
templateRenderer.render(LIST_ISSUES_TEMPLATE, context, resp.getWriter());
return;
}
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
issueInputParameters.setSummary(req.getParameter("summary"))
.setDescription(req.getParameter("description"))
.setAssigneeId(user.getName())
.setReporterId(user.getName())
.setProjectId(project.getId())
.setIssueTypeId(taskIssueType.getId());
IssueService.CreateValidationResult result = issueService.validateCreate(user, issueInputParameters);
if (result.getErrorCollection().hasAnyErrors()) {
List<Issue> issues = getIssues();
context.put("issues", issues);
context.put("errors", result.getErrorCollection().getErrors());
resp.setContentType("text/html;charset=utf-8");
templateRenderer.render(LIST_ISSUES_TEMPLATE, context, resp.getWriter());
} else {
issueService.create(user, result);
resp.sendRedirect("rungrovyscript");
}
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
ApplicationUser user = authenticationContext.getLoggedInUser();
String respStr;
IssueService.IssueResult issueResult = issueService.getIssue(user, req.getParameter("key"));
if (issueResult.isValid()) {
IssueService.DeleteValidationResult result = issueService.validateDelete(user, issueResult.getIssue().getId());
if (result.getErrorCollection().hasAnyErrors()) {
respStr = "{ \"success\": \"false\", error: \"" + result.getErrorCollection().getErrors().get(0) + "\" }";
} else {
issueService.delete(user, result);
respStr = "{ \"success\" : \"true\" }";
}
} else {
respStr = "{ \"success\" : \"false\", error: \"Couldn't find issue\"}";
}
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(respStr);
}
}
This is my code
and getting this error
2025-05-14 11:11:26,116+0530 http-nio-2990-exec-5 url: /jira/plugins/servlet/rungrovyservlet; user: admin ERROR admin 671x5659x1 e4v6gg 192.168.201.22 /plugins/servlet/rungrovyservlet [c.a.plugin.module.PrefixDelegatingModuleFactory] Detected an error instantiating the module via Spring. This usually means that you haven't created a <component-import> for the interface you're trying to use. https://developer.atlassian.com/x/TAEr for more details.
2025-05-14 11:11:26,116+0530 http-nio-2990-exec-5 url: /jira/plugins/servlet/rungrovyservlet; user: admin ERROR admin 671x5659x1 e4v6gg 192.168.201.22 /plugins/servlet/rungrovyservlet [c.a.plugin.servlet.DefaultServletModuleManager] Unable to create new reference LazyLoadedServletReference{descriptor=com.example.issuetest.issuedetail:run-grovy-servlet (The Run Grovy Servlet Plugin), servletContext=org.apache.catalina.core.ApplicationContextFacade@30e9781}
io.atlassian.util.concurrent.LazyReference$InitializationException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.issuetest.grovyscript.RunGrovyServlet': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atlassian.jira.bc.issue.IssueService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at io.atlassian.util.concurrent.LazyReference.getInterruptibly(LazyReference.java:156)
at io.atlassian.util.concurrent.LazyReference.get(LazyReference.java:116)
at com.atlassian.plugin.servlet.DefaultServletModuleManager.getInstance(DefaultServletModuleManager.java:431)
at com.atlassian.plugin.servlet.DefaultServletModuleManager.getServlet(DefaultServletModuleManager.java:410)
at com.atlassian.plugin.servlet.DefaultServletModuleManager.getServlet(DefaultServletModuleManager.java:230)
at com.atlassian.plugin.servlet.ServletModuleContainerServlet.service(ServletModuleContainerServlet.java:40)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
... 48 filtered
at com.atlassian.jira.plugin.mobile.web.filter.MobileAppRequestFilter.doFilter(MobileAppRequestFilter.java:59)
... 4 filtered
at com.atlassian.jira.plugin.mobile.login.MobileLoginSuccessFilter.doFilter(MobileLoginSuccessFilter.java:54)
... 3 filtered
at com.atlassian.diagnostics.internal.platform.monitor.http.HttpRequestMonitoringFilter.doFilter(HttpRequestMonitoringFilter.java:54)
... 8 filtered
at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
... 24 filtered
at com.atlassian.labs.httpservice.resource.ResourceFilter.doFilter(ResourceFilter.java:59)
... 27 filtered
at com.atlassian.oauth2.scopes.web.ReadWriteScopeFilter.doFilter(ReadWriteScopeFilter.java:46)
... 3 filtered
at com.atlassian.troubleshooting.thready.filter.AbstractThreadNamingFilter.doFilter(AbstractThreadNamingFilter.java:46)
... 17 filtered
at com.atlassian.jira.security.JiraSecurityFilter.lambda$doFilter$0(JiraSecurityFilter.java:66)
... 1 filtered
at com.atlassian.jira.security.JiraSecurityFilter.doFilter(JiraSecurityFilter.java:64)
... 16 filtered
at com.atlassian.pats.web.filter.TokenBasedAuthenticationFilter.doFilter(TokenBasedAuthenticationFilter.java:82)
... 3 filtered
at com.atlassian.oauth2.provider.core.web.AccessTokenFilter.doFilter(AccessTokenFilter.java:82)
... 23 filtered
at com.atlassian.jira.servermetrics.CorrelationIdPopulatorFilter.doFilter(CorrelationIdPopulatorFilter.java:30)
... 5 filtered
at com.atlassian.plugins.authentication.impl.basicauth.filter.DisableBasicAuthFilter.doFilter(DisableBasicAuthFilter.java:70)
... 8 filtered
at com.atlassian.web.servlet.plugin.request.RedirectInterceptingFilter.doFilter(RedirectInterceptingFilter.java:21)
... 4 filtered
at com.atlassian.troubleshooting.thready.filter.AbstractThreadNamingFilter.doFilter(AbstractThreadNamingFilter.java:46)
... 3 filtered
at com.atlassian.web.servlet.plugin.LocationCleanerFilter.doFilter(LocationCleanerFilter.java:36)
... 29 filtered
at com.atlassian.jira.servermetrics.MetricsCollectorFilter.doFilter(MetricsCollectorFilter.java:25)
... 24 filtered
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:750)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.issuetest.grovyscript.RunGrovyServlet': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atlassian.jira.bc.issue.IssueService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:378)
... 2 filtered
at java.lang.reflect.Method.invoke(Method.java:498)
at com.atlassian.plugin.osgi.spring.DefaultSpringContainerAccessor.createBean(DefaultSpringContainerAccessor.java:116)
at com.atlassian.plugin.module.ClassPrefixModuleFactory.createModule(ClassPrefixModuleFactory.java:34)
at com.atlassian.plugin.module.PrefixDelegatingModuleFactory.createModule(PrefixDelegatingModuleFactory.java:88)
at com.atlassian.plugin.servlet.descriptors.ServletModuleDescriptor.getModule(ServletModuleDescriptor.java:42)
at com.atlassian.plugin.servlet.DelegatingPluginServlet.<init>(DelegatingPluginServlet.java:30)
at com.atlassian.plugin.servlet.DefaultServletModuleManager$LazyLoadedServletReference.create(DefaultServletModuleManager.java:529)
at com.atlassian.plugin.servlet.DefaultServletModuleManager$LazyLoadedServletReference.create(DefaultServletModuleManager.java:513)
at io.atlassian.util.concurrent.LazyReference$Sync.run(LazyReference.java:332)
at io.atlassian.util.concurrent.LazyReference.getInterruptibly(LazyReference.java:150)
... 277 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atlassian.jira.bc.issue.IssueService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1357)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 295 more
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.