Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot and @ComponentScan between two jars

I have 2 projects. One is a DAL project that does CRUD operations on a neo4j DB using spring neo4j APIs . This project is packaged as a jar and included in project #2. Project #2 Is a Spring restful services project that uses spring boot to package and create an executable jar that runes on an embedded tomcat server.

When trying to run my executable jar that Spring boot has created for me I keep getting this exception. expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Based off of my reading if I am using @ComponentScan I can give the annotation directories to look in. So I give it the base dir for my services project. And I give it the base dir for my included DAL.jar but still no luck here is what the annotation looks like.

Extracted from comments:

Component scan declaration

@ComponentScan({"com.foo.dal.*","com.foo.notification.*"})

Stacktrace:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pushCommandsController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.teradata.dal.example.PushRepository com.teradata.notification.rest.controller.PushCommandsController.repository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.teradata.dal.example.PushRepository] 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)}

UPDATE:

based off of @chrylis answer: Made change to @ComponenetScan

@ComponentScan({"com.teradata.notification","com.teradata.dal"})

running in to:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration' is defined

MORE DETAIL ON THE DAL PROJECT AND THE SERVICE PROJECT:

DAL PROJECT:

DAL project structure


DAL classes


DAL classes


DAL classes


DAL classes


Services Project:

Service project structure


Service classes


Service classes


Service classes

like image 981
Muhi Masoud Avatar asked Mar 16 '14 20:03

Muhi Masoud


People also ask

What is @configuration @EnableAutoConfiguration and @ComponentScan?

@ComponentScan - to enable component scanning, all the packages and subpackages will be auto-scanned which are under the root package on which @SpringBootApplication is applied. @EnableAutoConfiguration - to enable auto-configuration of the. classes bases on the jars added in classpath.

What does @ComponentScan do in Spring boot?

One of the most important annotations in spring is @ComponentScan which is used along with the @Configuration annotation to specify the packages that we want to be scanned. @ComponentScan without arguments tells Spring to scan the current package and all of its sub-packages.

What is the difference between @component and @ComponentScan in Spring?

@Component and @ComponentScan are for different purposes. @Component indicates that a class might be a candidate for creating a bean. It's like putting a hand up. @ComponentScan is searching packages for Components.

Which of the following is best practices of using @ComponentScan annotation in Spring?

A good practice is to explicitly import a @Configuration class with the @Import annotation and add the @ComponentScan annotation to that configuration class to auto-scan only the package of that class. This way, we have clean boundaries between the packages of our application.


2 Answers

The argument to @ComponentScan is a package name, and those strings aren't valid packages. Drop the .* from them; Spring scans subpackages automatically.

like image 81
chrylis -cautiouslyoptimistic- Avatar answered Oct 17 '22 11:10

chrylis -cautiouslyoptimistic-


Had this same issue for a short while, then @EntityScan did the trick for me, just as adviced here - Spring Boot w/ JPA: move @Entity to different package.

Hope that helps

like image 2
Tomek Samcik Avatar answered Oct 17 '22 10:10

Tomek Samcik