4

I'm currently trying to develop a custom Jira plugin, which also uses a servlet to render a Soy template.

This is the code of my servlet:

    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package at.fraiss.plugins.custommenuitem.servlets;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.atlassian.soy.renderer.SoyTemplateRenderer;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Mario
 */
public class SoyTemplateServlet extends HttpServlet {

    private SoyTemplateRenderer soyTemplateRenderer;

    public SoyTemplateServlet(SoyTemplateRenderer soyTemplateRenderer)
    {
        this.soyTemplateRenderer = soyTemplateRenderer;
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        response.setContentType("text/html");
        response.getWriter().write(getHtml());
    }

    public String getHtml()
    {
        Map<String, Object> data = new HashMap<String,Object>();
        data.put("isLocal", true);
        data.put("url", "http://www.example.com");
        data.put("title", "example");
        return this.soyTemplateRenderer.render("jira.webresources:soy-templates", "JIRA.Templates.Links.helpLink", data);
    }
}

This is how I defined the soy template files inside the atlassian-plugin.xml descriptor:

<web-resource key="soy-templates">
    <dependency>com.atlassian.soy.soy-template-plugin:soy-deps</dependency>


    <!-- Available to the server-side only -->
    <resource type="soy" name="links" location="links.soy"/>
 
    <!-- Make available to the client-side in JS as well... -->
    <transformation extension="soy">
        <transformer key="soyTransformer"/>
    </transformation>
    <resource type="download" name="Links.soy.js" location="links.soy"/>
</web-resource>

I have added the following section to my pom.xml:

<dependency>
        <groupId>com.atlassian.soy</groupId>
        <artifactId>soy-template-renderer-api</artifactId>
        <version>4.0.4</version>
        <scope>provided</scope>
    </dependency>

and always get this error when try to acces the servlet

[INFO] [talledLocalContainer] Caused by: org.springframework.beans.factory.Unsat isfiedDependencyException: Error creating bean with name 'at.fraiss.plugins.cust ommenuitem.servlets.SoyTemplateServlet': Unsatisfied dependency expressed throug h constructor argument with index 0 of type [com.atlassian.soy.renderer.SoyTempl ateRenderer]: : No qualifying bean of type [com.atlassian.soy.renderer.SoyTempla teRenderer] found for dependency: expected at least 1 bean which qualifies as au towire candidate for this dependency. Dependency annotations: {}; nested excepti on is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualif ying bean of type [com.atlassian.soy.renderer.SoyTemplateRenderer] found for dep endency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.Con structorResolver.createArgumentArray(ConstructorResolver.java:749) [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.Con structorResolver.autowireConstructor(ConstructorResolver.java:185) [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.Abs tractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanF actory.java:1139) [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.Abs tractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFa ctory.java:1042) [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.Abs tractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory. java:504) [INFO] [talledLocalContainer] at org.springframework.beans.factory.support.Abs tractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.ja va:342) [INFO] [talledLocalContainer] ... 2 filtered [INFO] [talledLocalContainer] at java.lang.reflect.Method.invoke(Method.java:4 97) [INFO] [talledLocalContainer] at com.atlassian.plugin.osgi.spring.DefaultSprin gContainerAccessor.createBean(DefaultSpringContainerAccessor.java:112) [INFO] [talledLocalContainer] at com.atlassian.plugin.module.ClassPrefixModule Factory.createModule(ClassPrefixModuleFactory.java:39) [INFO] [talledLocalContainer] at com.atlassian.plugin.module.PrefixDelegatingM oduleFactory.createModule(PrefixDelegatingModuleFactory.java:100) [INFO] [talledLocalContainer] at com.atlassian.plugin.servlet.descriptors.Serv letModuleDescriptor.getModule(ServletModuleDescriptor.java:48) [INFO] [talledLocalContainer] at com.atlassian.plugin.servlet.DelegatingPlugin Servlet.<init>(DelegatingPluginServlet.java:33) [INFO] [talledLocalContainer] at com.atlassian.plugin.servlet.DefaultServletMo duleManager$LazyLoadedServletReference.create(DefaultServletModuleManager.java:5 41) [INFO] [talledLocalContainer] at com.atlassian.plugin.servlet.DefaultServletMo duleManager$LazyLoadedServletReference.create(DefaultServletModuleManager.java:5 21) [INFO] [talledLocalContainer] at com.atlassian.util.concurrent.LazyReference$S ync.run(LazyReference.java:325) [INFO] [talledLocalContainer] at com.atlassian.util.concurrent.LazyReference.g ...

TylerH
  • 20,799
  • 66
  • 75
  • 101
Mario Fraiß
  • 1,095
  • 7
  • 15

2 Answers2

7

I also had this problem (and lost hours on it).

The Spring scanner apparently only processes classes marked with @Named.

This worked for me:

@Named("MyServlet")
public class MyServlet extends HttpServlet{
    @ComponentImport
    private final SoyTemplateRenderer soyTemplateRenderer;

    @Inject
    public MyServlet(@ComponentImport final SoyTemplateRenderer soyTemplateRenderer) {
        this.soyTemplateRenderer = soyTemplateRenderer;
    }
}
-4

Apparently this has nothing to do with jiira, but in your frustration you seem to be blaming it and its documentation. It's actually a problem with your use of spring, and your apparent inability to read stack traces.

The first entry in the stack trace mentions, in may different ways, No qualif ying bean of type [com.atlassian.soy.renderer.SoyTemplateRenderer] found. So, you seem to have not provided a bean definition for the SoyTemplateRenderer for spring to find. Rectify this and this particular problem will disappear.

Software Engineer
  • 15,457
  • 7
  • 74
  • 102