Springboot custom autoconfiguration in Gradle not loading - spring-boot

So I have I built a custom Springboot starter and autoconfiguration and everything builds fine, the code is all their in the local maven repo.
I even checked the generated jars and everything looksgood.
Can't load the generated files into the project but when I look at the generated beens, there is no sign of beans created by autoconfiguration (or the autoconfiguration itself) : https://github.com/orubel/spring-boot-starter-beapi/issues/37
Project code can be sen here: https://github.com/orubel/spring-boot-starter-beapi/blob/main/beapi-lib/build.gradle
what am I doing wrong that implementations can';t see the beans?
I have tried bringing in the dependencies from mavenLocal() with:
implementation "io.beapi:beapi-lib:0.4"
implementation "io.beapi:beapi-spring-boot-starter:0.4"
and with:
implementation "io.beapi:beapi-lib:0.4"
implementation "io.beapi:beapi-spring-boot-autoconfigure:0.4"
Both have the same error of stating that an AUTOWIRED bean (from the autoconfiguration) cannot be found:
Consider defining a bean of type 'io.beapi.lib.service.PrincipleService' in your configuration.
If I comment out the autowired bean, it just throws error that bean is null.

Ok solved my issue.
As I am instantiating the beans from a library I am creating through the starter, I have to do a '#ComponentScan' on those classes.
So just adding:
#ComponentScan(["io.beapi.lib.service"])
To the application main class was enough to resolve this :)

Related

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.

How to add Spring dependency injection to a sub-module of a project not using Spring before

Noobish question here, but I'm struggling to make this work.
I've an old project with submodules which does not use Spring or anything, just final class and static Instance.
--- Main
------ Server
------ Business
------ Webservices
Server has a dependency with Business and Webservices.
Webservices has a dependency with Business
Server is the sub-module with the web.xml file.
I have to add a new service in Business sub-module and I want to start using Spring and dependency injection to do so, in order to start migrating the project to Spring.
(I'm not talking SpringBoot, just regular Spring).
In Business sub-module, I did:
add spring-core, spring-beans, spring-contet dependencies as well as javax.inject .
Using spring version 4.3.2
create an interface IMyService and its implementation MyServiceImpl and added the #Service annotation on the impl.
add a spring-context.xml file in src/main/resources declaring context:annotation-config and context:component-scan base-package
Then I created, in my submodule a "bridge" to try and use the Spring bean from my submodule in a non spring bean of another submodule, like described here : https://blog.jdriven.com/2015/03/using-spring-managed-bean-in-non-managed-object/
However the context never get injected.
I've tried adding in the web.xml of Server the contextConfigLocation but no dice either.
What Am I missing so that my Spring context get initialized in the Business module ?

Intellij IDEA parse custom bean - cannot find custom handler for namespace

<camel:camelContext id="myCamelContext">
<camel:routeBuilder ref="route"/>
</camel:camelContext>
I try to parse the bean above in Intellij IDEA ("Parse custom bean"), but get the following error:
Cannot find custom handler for namespace 'http://camel.apache.org/schema/spring'
The IDE also displays an error for any corresponding #Autowired annotations in my test code, although the tests run successfully. The application works at runtime, and I have camel-spring as a maven dependency. It only has problems in the IDE.
The camel-spring maven dependency was at "runtime" scope. While technically this is correct, this made it unavailable to Intellij when coding. Changing the maven scope to "compile" enabled Intellij to use the the camel spring bean handler for interpreting the bean.

conflicts with existing, non-compatible bean definition of same name and class after proguard obfuscation

after Proguard obfuscation i get the following error :
Unexpected exception parsing XML document from ServletContext resource
[/WEB-INF/applicationContext.xml]; nested exception is
java.lang.IllegalStateException: Annotation-specified bean name 'a'
for bean class [com.company.project.b.a.a.a] conflicts with existing,
non-compatible bean definition of same name and class
[com.company.project.a.a]
i'm using annotation based spring configuration , how can i avoid having two classes with the same name using Proguard because Spring doesn't allow two beans to have the same name.
I'm not sure if this is what you want, but you can specify bean name in #Component (and stereotypes #Repository, #Service and #Controller) value:
#Component("myBeanName")
public class MyBean {
}
I had the same problem and nothing else was helping out. Sometimes the problem occurs if you have moved your classes around and it refers to old classes, even if they don't exist.
In this case, just do this :
mvn eclipse:clean
mvn eclipse:eclipse
This worked well for me.
Another cause; you may have different versions of Spring in your classpath, for example, spring 2.x with spring 3.x. In such condition, beans seem to be loaded twice. If you use maven, check if a module does not import an old version of Spring (mvn dependency:tree) and remove it by excluding the involved spring artifact (exclusions).

Is it possible to autowire dependencies that are created outside of an ApplicationContext?

I've got an application which uses JAXRS to map Restlet resources using annotations. However, the only entry point I have is essentially defining a list of resource classes in the application configuration. These classes are instantiated by Restlet or JAXRS, so I have no way to put them in my ApplicationContext. Is there a way to have Spring scan the classpath and autowire new instances as necessary? I've already tried using something like below:
#Autowired
private SessionFactory sessionFactory;
Unfortunately, it doesn't really work. Is there a way to do what I'm talking about here?
You can use AspectJ to dependency inject your beans that are created out of your control, or if you create objects using new. You can read more on Springs documentation: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-using-aspectj
Essentially what you will do is add #Configurable annotation to the class that you want to be target of injection. You also have to enable it in Spring by having in your Spring xml. Lastly you have to decide between compile time weaving or runtime weaving. Again you can get help from spring documentation.
Loadtime weaving: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-aj-ltw
If you use maven you can check this Stackoverflow question for setting up compile time AspectJ: Why doesn't AspectJ compile-time weaving of Spring's #Configurable work?
ApplicationContext.getAutowireCapableBeanFactory().autowireBean(object) will inject all dependencies into the object.

Resources