Spring not recognising some #Configuration and #Component classes - spring

I have - or rather had - a working Spring application, running within IntelliJ. It contains several classes annotated with #Configuration, and several #Component beans. At some point, the following happened:
Intelli started showing errors in the code editor stating "Could not autowire. No bean of 'xxx' type found". But there are such beans which are annotated with #Component.
Breakpoints in the constructor of specific #Component beans are not reached. But that is not true for all #Component beans.
When running in debug mode, breakpoints in certain #Configuration files are not reached, even though the debugger was stopping there before. The application will fail if it is autowired with one of these #Component beans.
The application starts without errors, but obviously without several beans configured in #Configuration classes being called.
The class which contains the main method which runs the Spring Boot application is annotated with #SpringBootApplication. #Component classes which live in the same package as this class are recognised and can be autowired, even into classes in other packages.
I am not aware of anything in the code or project which would have changed.
Under File -> Project Settings -> Modules, under Spring Application Context have now selected all #Configuration files. However this makes no difference.
Have also tried Build -> Rebuild Project.
The packages in which the classes reside have not changed. Has anyone seen anything like this before?
Thanks

If few classes are not getting recognised #Component. Then it could be the case that those classes don't come under the same package. You must have observed that the classes under the same package as of Main class of #SpringBootApplication, got recognised with #Component because #SpringBootApplication defines an automatic #ComponentScan on the package.
So other classes which were defined in some other package are not recognised because there is no #ComponentScan for those classes' package.
You can do the following to get those classes recognised(add the other packages which are not directly under the hierarchy of #SpringBootApplication):
#ComponentScan({"com.example.springboot.anything","com.example.springboot.somethingelse"})
#SpringBootApplication
public class AnySpringBootApplication {

I am sure it will not be a common case, but for me the problem was that my class had a relatively generic name. Although it was located in the package mentioned in the ComponentScan, on the same level with other classes all found and used, I kept having problems that the ApplicationContext failed to load. After I renamed the class it worked, I found that two other classes in org.springframework had the same name.

Related

Mock Bean for all JUnit Tests in Spring Boot

In Spring Boot, is there a way to mock a single bean for all existing JUnit tests, without changing the existing test classes (e.g., by adding an annotation or adding inheritance)? Like injecting a bean globally via configuration.
Assuming you are using #SpringBootApplication in your main sources to define the Spring Boot application, you'll already have component scanning enabled for everything in that package (including nested packages).
When running tests, the classes (typically) in src/test/java are also added to the classpath, and are therefore available to be scanned as well.
For example, if you defined your #SpringBootApplication at com.example.boot.MySpringBootApplication, then com.example.boot.MyTestConfiguration would be eligible for component scanning, even though the former is in src/main and the latter in src/test. Putting it in the src/test/java directory would ensure that it only has an effect while running tests.
You can then define any "global" beans you would like in that configuration.
Using the package/class names I provided:
// File: src/test/java/com/example/boot/MyTestConfiguration.java
#Configuration // this will get component-scanned
public class MyTestConfiguration {
#MockBean
MyBean myGlobalMockBean;
}
Then, so long as you don't omit that Configuration from the Context Configuration, the MockBean should always be present under test.

cannot Autowire a class from external jar in spring boot

Have a class A in a spring boot application. Have added a module in the pom, and i am able to import that class 'B' from that module in this class
but i am not able to autowire the same,
#EnableAutoConfiguration
class A
{
A(B b)
}
There are no compile time errors, but the application fails to start
Parameter 0 of method <> required a bean of type <> that could not be found
Tried annotating the main class with #ComponentScan({"package of class B"}) , no compile errors, but the application fails to start with same error, but with different classes.
thoughts ?
If you specify #ComponentScan with a specific package, Spring will only scan that package and subpackages for Spring beans. So if your different classes are in a different package structure, you have to add those packages as well in the annotation.

Springboot build not working because of test configuration

I have started a spring boot project using start.spring.io.
But I am getting this error-
I have read various articles on the internet about this issue and they all say about putting my tests in the same package as my Main class.
But I already have the same.
Could you point out what is wrong with my configuration?
The exception is pretty clear: You are missing a configuration for your spring context. What you need to do is to add the configuration classes for your context like so:
#SpringBootTest(classes = { TestConfiguration.class })
whereas your TestConfiguration class must be annotated with
#Configuration
and/or
#EnableAutoConfiguration
There you can add configurations to your liking. You can of course also use your DatabaseApplication class as Configuration although Im wouldn't recommend that.
The search algorithm works up from the package that contains the test until it finds a #SpringBootApplication or #SpringBootConfiguration annotated class. As long as you’ve structure your code in a sensible way your main configuration is usually found.
Make Sure your DatabaseApplication class is annotated with #SpringBootApplication .

Spring AOP aspect doesn't get applied if included from an external jar with different package name

I have a spring boot rest service that included an external project in pom as it's dependency. That external project is basically a jar that has spring AOP code.
The base package in my main application that includes this external jar with spring AOP code is x.y.z
The class in external jar where the #before advice is, is under the package a.b.c
With this class under a.b.c package, it doesn't get recognized by the main application where I want to use the spring aop implementation and apply the aspect. However, when I change it's package from a.b.c to x.y.z (which I really can't do in real life) it works fine.
I know that in spring boot service which happens to be the including service, it scans everything under root package given in the application class, x.y.z in this case and that is why aspect works fine if it's class is under x.y.z.
however, the problem is that this spring app jar will be used across multiple applications. So changing package name like this is not an option.
Is there a way to accomplish this without changing the package name of the class where spring app code is ?
Probably component scan is only activated for your application class packages by default. You can extend it to multiple packages, including the aspect package:
XML style configuration:
<context:component-scan base-package="x.y.z, a.b.c" />
Annotation style configuration:
#ComponentScan(basePackages = {"x.y.z", "a.b.c"})
Disclaimer: I am not a Spring user, only an AspectJ expert. I just knew that you can configure component scan, googled the syntax for you and hope it is correct.
Please define the bean (of jar project )inside main application. Give the #ComponentScan(basePackages = {"x.y.z", "a.b.c"}) as well as #EnableAspectJAutoProxy. Also include below piece of code.
ex:
` #Bean
public LoggingHandler loggingHandler()
{
return new LoggingHandler();
}`
Also annotate external jar code with:
`#Aspect
#Component
public class LoggingHandler {`
What #kriegaex suggests is correct. In addition to that, please make sure you are using #Component along with #Aspect. Since #Aspect is not a Spring annotation, Spring won't recognize it and hence your aspect won't be registered. So, using #Component is mandatory to getting aspects to work in Spring environment.

Wiring a bean from dependency module

I have created a configuration project which essentially creates couple of beans with configuration stereotype. Then, I want this project to be reused across by my clients.
I have added this config project as a maven dependency, but my client project is not having those beans i have created as part of configuration project.
Could someone help
Ok, the answer is the following: you should place
#ComponentScan("you.configurations.base.package")
on one of your configuration (in the current application, one that #SpringBootApplication sees) or on the class with #SpringBootApplication annotation.
The explanation is as follows: #SpringBootApplication under the hood contains #ComponentScan without specifying a base package. That means that it says to Spring to scan the package where the class annotated with #SpringBootApplication resides and all the packages recursively. And that's it. If you place you #Configuration somewhere there - it will create it during startup, otherwise not.
We can resolve this by enabling spring-boot autoconfiguration
Create classpath->resources->META-INF->spring.factories file
org.springframework.boot.autoconfigure.EnableAutoConfiguration=[add your class with you need to be loaded during application load time]

Resources