Reputation: 5813
I get a classic org.springframework.beans.factory.BeanCreationException:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Server': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private MyClass Server.myClass; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [MyClass] 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)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at root.package.Application.main(Application.java:14)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private MyClass Server.myClass; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [MyClass] 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)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 12 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [MyClass] 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)
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.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545)
... 14 more
"MyClass" in the stack trace above is of course the FQN of my class, which I replaced in this case (I can't show my package). It's a simple Netty Handler:
@Service
public class MyClass extends SimpleChannelInboundHandler<Protocol> implements Visitor {
@Autowired
private RestTemplate restTemplate;
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Protocol protocol) throws Exception {
channelHandlerContext.writeAndFlush(protocol.accept(this, channelHandlerContext));
}
public Object visit(Protocol protocol, ChannelHandlerContext channelHandlerContext) {
return restTemplate.exchange(...);
}
}
The class that depends on MyClass:
@Component
public class Server {
@Autowired
private MyClass myClass;
private ChannelFuture serverChannelFuture;
@PostConstruct
public void start() throws Exception {
serverChannelFuture = bootstrap().bind(tcpPort()).sync();
}
@PreDestroy
public void stop() throws Exception {
serverChannelFuture.channel().close();
serverChannelFuture.channel().closeFuture().sync();
}
private ServerBootstrap bootstrap() {
// Bootstrap setup
}
}
And my configuration:
@Configuration
@ComponentScan("root.package")
public class SpringConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public Logger logger() {
return Logger.getLogger(InternalLoggerFactory.class.toString());
}
}
All my classes are in either root.package or a subpackage of it. MyClass is in a subpackage as well.
I have no idea why this would cause the above Exception. I have other Services in my root.package package that are being autowired just fine! Does any one have an idea?
EDIT: after some further testing, it appears the "visit" method is the problem. If I rename it, the application boots fine. Could this be a bug in Spring?
EDIT 2: I celebrated too early. I renamed the method in my Visitor interface and now I'm back to the same problem. Even if I comment out my interface, I cannot have any method with the same name as that interface. MyClass is the only class that implements Visitor that is a Spring bean.
Upvotes: 1
Views: 3371
Reputation: 5813
This answer set me on my way: Spring instantiates bean but can't use it
The problem was that I use Spring aspects as well, which are configured with
@EnableAspectJAutoProxy
However, by default, this enables JDK proxies, which work differently (see the answer of that question for more info).
@EnableAspectJAutoProxy(proxyTargetClass=true)
Enables CGLIB proxies, which was the solution to my problem.
Upvotes: 0
Reputation: 16984
The thing about Spring annotations is that classes must reside in the same package tree as the runner or context.
For example, if your Spring application class is in com.dippity.dot.myapp
all other classes annotated as @Service
, @Component
, etc must also be down the com.dippity.dot.myapp
package tree.
A @Service
annotated package could live com.dippity.dot.myapp.service
and work.
Upvotes: 0
Reputation: 131
Your class MyClass has no package name?
"No qualifying bean of type [MyClass]"
in your Configuration you set the componentscan to a specififc package
@ComponentScan("root.package")
so Spring could not found your beans.
to fix: remove ("root.package") or add the package "root.package" to your classes
Upvotes: 1