Jira Plugin development | Servlet issue

Rickard Forslund March 9, 2021

I am a student working on developing a plugin for JIRA, and have been having trouble getting my servlet to read my html file. So now I wonder which annotations are right to use ?, and what dependencies?. I don't get any error messages, I just can't open the index.vm page.

Would really appreciate if anyone could take a look at my code in the link that i  attach below, or just help me find the right person who is knowledgeable in this area.

Thanks for help :)

https://stackoverflow.com/questions/66554458/jira-plugin-development-servlet-issue

1 answer

1 accepted

0 votes
Answer accepted
Martin Bayer _MoroSystems_ s_r_o__
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 9, 2021

Hi @Rickard Forslund , welcome on the community :)

When developing with Atlassian SDK, you need to add servlet description to atlassian-plugin.xml as described in this "how to" article

https://developer.atlassian.com/server/jira/platform/servlet/

I don't know if it is what you need, but eventually get back to me so we can fix it :)

Rickard Forslund March 10, 2021

i Martin, first of all I want to thank you for taking your time to look at my problem, appreciated! I double checked my atlassian-plugin.xml file and it seems that I already have a description in my servlet.

<description key="sumalizer-servlet.description">The Sumalizer Servlet Plugin</description>

 

what could it be besides that?, any thoughts?

Martin Bayer _MoroSystems_ s_r_o__
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 10, 2021

HI @Rickard Forslund , ok, I didn't check it precisely, I thought link leads to some "old" stackoverflow issue... sorry :).

I would adjust "variables" and "constructor" part to this:

    private final VelocityManager velocityManager;
    private final PageBuilderService pageBuilderService;
    private final IssueManager im;
    private final TemplateRenderer tr;


    private static final Logger log = LoggerFactory.getLogger(
            SumalizerServlet.class
    );

    @Autowired
    public SumalizerServlet(@ComponentImport VelocityManager velocityManager, 
@ComponentImport PageBuilderService pageBuilderService,
@ComponentImport IssueManager im,
@ComponentImport TemplateRenderer tr)
{ this.velocityManager = velocityManager; this.pageBuilderService = pageBuilderService; this.im = im; this.tr = tr; }

where Autowired is from package 

org.springframework.beans.factory.annotation

I would also add some logging to doGet method. It is weird there are no errors in your atlassian-jira.log log file. 

Rickard Forslund March 10, 2021

Ye okay, I changed what you said, I already had dependency from all 100 attempts I already made hehe,  and now I actually get error messages again, saying.

 

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.i3tex.plugin.servlet.SumalizerServlet': Unsatisfied dependency expressed through constructor argument with index 0 of type [com.atlassian.velocity.VelocityManager]: No qualifying bean of type [com.atlassian.velocity.VelocityManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport(value=)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.atlassian.velocity.VelocityManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport(value=)}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:342)
... 2 filtered
at java.lang.reflect.Method.invoke(Method.java:498)
at com.atlassian.plugin.osgi.spring.DefaultSpringContainerAccessor.createBean(DefaultSpringContainerAccessor.java:97)
at com.atlassian.plugin.module.ClassPrefixModuleFactory.createModule(ClassPrefixModuleFactory.java:35)
at com.atlassian.plugin.module.PrefixDelegatingModuleFactory.createModule(PrefixDelegatingModuleFactory.java:88)
at com.atlassian.plugin.servlet.descriptors.ServletModuleDescriptor.getModule(ServletModuleDescriptor.java:43)
at com.atlassian.plugin.servlet.DelegatingPluginServlet.<init>(DelegatingPluginServlet.java:30)
at com.atlassian.plugin.servlet.DefaultServletModuleManager$LazyLoadedServletReference.create(DefaultServletModuleManager.java:545)
at com.atlassian.plugin.servlet.DefaultServletModuleManager$LazyLoadedServletReference.create(DefaultServletModuleManager.java:529)
at com.atlassian.util.concurrent.LazyReference$Sync.run(LazyReference.java:325)
at com.atlassian.util.concurrent.LazyReference.getInterruptibly(LazyReference.java:143)
... 233 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.atlassian.velocity.VelocityManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport(value=)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)  
Rickard Forslund March 10, 2021

ye okay, i changed what you said, i already had the dependency from all the 100 attempts i already made hehe, and now i actualy getting some errors

And should the Class realy be annotated with @Component?

 

errors.png

Martin Bayer _MoroSystems_ s_r_o__
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 11, 2021

Hi @Rickard Forslund , yes, @Component and @Autowired annotations are correct... the question is why VelocityManager is not loaded... I will try to check it, but will need some time.

Rickard Forslund March 11, 2021

Okay sure, getin touch if you manage to solve anything Martin :)

Martin Bayer _MoroSystems_ s_r_o__
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 11, 2021

I found one snippet of code we have and it uses 

com.atlassian.jira.template.VelocityTemplatingEngine

Could you give it a try? You just need to replace VelocityManager with VelocityTemplatingEngine in constructor and class properties.

Snippet of code we use is:



private void addContextToParams(final Map<String, Object> templateParams) {
templateParams.put("baseUrl", applicationPropertiesFacade.getBaseUrl());
templateParams.put("runDate", LocalDate.now().format(DATE_FORMATTER));
}
private String constructEmailBody(final String templatePath, final Map<String, Object> templateParams) {
addContextToParams(templateParams);

return velocityTemplatingEngine.render(TemplateSources.fragment(getTemplateContent(templatePath)))
.applying(templateParams)
.asHtml();
}

private String getTemplateContent(final String resourceName) {
try {
return IOUtils.toString(this.getClass().getResourceAsStream(resourceName), Charset.defaultCharset());
} catch (IOException e) {
// handle exception
}
}

 and resourceName is path to your template, in your case it should be

"/templates/index.vm"
Rickard Forslund March 22, 2021

Hi again @Martin Bayer _MoroSystems_ s_r_o__ , I have been busy so haven't got time to answer you, I tried with your solution to the problem but didn't manage to get it to work , but got another tip that I could use webwork instead and that it would basicly work the same way, so i tried it out and  finally  got it to work! Now I try to make an api call to: jira/rest/api/2/search. but don't really know how to proceed, do you have some awesome tips or good approach to me? :), i also want to be able to pass in a jql string and get the information to a table on my webwork page,  Thanks for all your help

Martin Bayer _MoroSystems_ s_r_o__
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 22, 2021

Hi @Rickard Forslund could you please create new topic and mention me eventually? We must try to have the Community portal as clean as possible.

But one small hint can be... In Java code, I would use SearchService (https://docs.atlassian.com/software/jira/docs/api/7.6.1/index.html?com/atlassian/jira/bc/issue/search/SearchService.html) instead of REST API, if there is no reason to use REST API.

Suggest an answer

Log in or Sign up to answer