0

I'm building an application that connects to a Stardog database via the Snarl API alongside Springboot for the front end. The autowired beans for the snarlTemplate are working fine, but any Components I defined are having issues. I've taken out the autowiring for the ValidationDAO and gotten it to load. I've looked at the other posts with this same problem, but I couldn't get a solution.

First off, here's the DAO (which I have annotated as a component)... Validation is a POJO defined in a different file.
src/main/java/validation/ValidationDAO.java

@ComponentScan("com.complexible.stardog.ext.spring")
@Component
public class ValidationDAO {

    private static final Logger logger = LoggerFactory.getLogger(ValidationDAO.class);

    @Autowired
    public SnarlTemplate snarlTemplate;

    public List<Validation> validate() {

        // TODO: file input

        String query = "SELECT * WHERE { ?s ?p ?o }";

        logger.debug("DAO Query: " + query);
        List<Validation> results = snarlTemplate.query(query, new RowMapper<Validation>() {

            public Validation mapRow(BindingSet bindingSet) {
                Validation v = new Validation();

                // set results of query
                v.setSubject(bindingSet.getValue("s").stringValue());
                v.setPredicate(bindingSet.getValue("p").stringValue());
                v.setObject(bindingSet.getValue("o").stringValue());

                // set error message
                v.setError("No given description.");

                return v;
            }
        });

        return results;
    }

    public SnarlTemplate getSnarlTemplate() {
        return snarlTemplate;
    }

    public void setSnarlTemplate(SnarlTemplate snarlTemplate) {
        this.snarlTemplate = snarlTemplate;
    }

}

And then here's the HomeController:
src/main/java/validation/HomeController.java

@RestController
public class HomeController {

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    public ValidationDAO validationDAO;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {

        List<Validation> results = validationDAO.validate();
        logger.debug("Found " + results.size() + " errors in ontology.");
        model.addAttribute("results", results);
        return "home";

    }

    public ValidationDAO getValidationDAO() {
        return validationDAO;
    }

    public void setValidationDAO(ValidationDAO validationDAO) {
        this.validationDAO = validationDAO;
    }

}

Root context:
src/main/webapp/WEB-INF/spring/root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <context:component-scan base-package="src.main.java.validation"/>
     <context:annotation-config/>

    <bean name="dataSource" class="com.complexible.stardog.ext.spring.DataSourceFactoryBean">
        <property name="to" value="validationTest"/>
        <property name="username" value="admin"/>
        <property name="password" value="admin"/>
        <property name="url" value="snarl://localhost:5820"/>
    </bean>

    <bean name="template" class="com.complexible.stardog.ext.spring.SnarlTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

Finally, the full error message.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public validation.ValidationDAO validation.HomeController.validationDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validationDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.complexible.stardog.ext.spring.SnarlTemplate validation.ValidationDAO.snarlTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.complexible.stardog.ext.spring.SnarlTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
    at validation.Application.main(Application.java:14) [main/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public validation.ValidationDAO validation.HomeController.validationDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validationDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.complexible.stardog.ext.spring.SnarlTemplate validation.ValidationDAO.snarlTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.complexible.stardog.ext.spring.SnarlTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 17 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validationDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.complexible.stardog.ext.spring.SnarlTemplate validation.ValidationDAO.snarlTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.complexible.stardog.ext.spring.SnarlTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 19 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.complexible.stardog.ext.spring.SnarlTemplate validation.ValidationDAO.snarlTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.complexible.stardog.ext.spring.SnarlTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 30 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.complexible.stardog.ext.spring.SnarlTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    ... 32 common frames omitted
R Jackson
  • 105
  • 3
  • 13

2 Answers2

2

The ComponentScan-annotation should be in a configuration and not in the component class. I really don't know if it works at all and it contains a package you don't mention.

Second point: Don't use field injection. (http://olivergierke.de/2013/11/why-field-injection-is-evil/)

Now back to the problem: I think your component scan in the xml file is wrong or your packages have some confusing names. But I am pretty sure this is your maven/gradle file path ;) It should not contain the file path but only the package validation.

<context:component-scan base-package="validation"/><context:annotation-config/>
meistermeier
  • 7,942
  • 2
  • 36
  • 45
  • How would I set up the ComponentScan in a configuration? Should that be a Configuration java file? Sorry, the annotations are new to me and I'm sure I'm using them incorrectly. Also, I tried the package "validation" and it still failed. – R Jackson May 19 '16 at 13:39
  • Since you are using SpringBoot, you could start with applying the `@ComponentScan`Annotation to your entry point class (the one that starts the spring boot application). Sample at the end of the page: http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-structuring-your-code.html – meistermeier May 19 '16 at 13:44
  • Oh! That makes a lot of sense. It's still not running, so I might just have to go back and restructure everything. I think the problem is with the XML, so I might try and remove that and do everything with the spring configuration. – R Jackson May 19 '16 at 13:56
  • I also think you should avoid xml configuration files. In my opinion there is no "mainstream" use case for them anymore. I would suggest to put your whole configuration (it does not seem so much ;) ) in the config class after you structured your packages. If the application works you can refactor and split your configuration in multiple configuration classes. – meistermeier May 19 '16 at 14:11
  • Thanks, I'll look into redoing my configuration that way! – R Jackson May 19 '16 at 18:26
0

You are sure your xml configuration is loaded?

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-importing-xml-configuration

Maxvader
  • 115
  • 7
  • I believe so, since the Snarl Template got loaded in when I removed the autowiring from ValidationDAO. Do you think it would be better to get rid of the XML configuration (like they say) and do a @Configuration class? – R Jackson May 19 '16 at 13:37
  • Personally I'm not a huge fan of annotation only configuration. I find difficult to chase all classes that are annotated and very complicated to change implementations of interfaces depending on various configurations. I use annotations for things that don't change and XML for things that can be configured. So my product configuration is in one file. – Maxvader May 19 '16 at 14:18
  • I've made a few test, and built your configuration with mock classes. To me it seems that xml is never read. Just moving the Configuration annotation in the @SpringBootApplication class did the magic. – Maxvader May 19 '16 at 14:54
  • And just to countercheck, if you manage to really load the xml, it creates the object to be injected and you don't need to use componentScan... – Maxvader May 19 '16 at 15:02
  • Huh, that's strange. I tried moving the Configuration annotation and it didn't work for me... I wonder what's different between the two. – R Jackson May 19 '16 at 18:19