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

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).

Related

springboot app looking for GenericResponseService bean

I am new to springboot.
Doing a migration of my service (kotlin)following a guide written at work.
Got this weird exception and cannot find any documentation.
Parameter 3 of method multipleOpenApiResource in org.springdoc.webflux.core.MultipleOpenApiSupportConfiguration required a bean of type 'org.springdoc.core.GenericResponseService' that could not be found.
Action:
Consider defining a bean of type 'org.springdoc.core.GenericResponseService' in your configuration.
Should I define this bean at my #Configuration?
Is this a symptom of dependency missing or bad dependency wiring?
One of my beans was called ResponseBuilder and it conflicted with spring boot.
Sorry for the trouble

Springboot custom autoconfiguration in Gradle not loading

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 :)

External Java Library issue with Autowiring and injecting bean

I have created a Spring Boot application managed by Maven.
I'm retrieving an company's library from our Maven repository.
In this library, we have a service interface, not being annotated with '#Service':
public interface MyService {
//...
}
This service has only one implementation :
public class DefaultMyService implements MyService {
//...
}
This library context is managed the old Spring way (in applicationContext.xml file).
I read that normally, Spring Boot is able to find the implementation if there's only one in the scope.
When I try to run "spring-boot:run" on my project, it will fail with the following error :
No qualifying bean of type 'com.pharmagest.saml.SAMLService'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
I tried:
To add a #ComponentScan on the configuration class, including packages in error : #ComponentScan(basePackages={"com.mycompany.web", "com.mycompany.thelibrary.client.*", "com.mycompany.thelibrary.services.*"})
To add the bean definition in applicationContext.xml (if I add the interface it tells me it can define it, thus I heard that Spring can find the default implementation if there is only one ?)
To add library at "runtime" in projects options
To add the library as external resource not via maven
In all cases I just can maven build but can't run the project.
Do you have any advice to help me ? thanks!
Won't work as the DefaultMyService has no #Component (or #Service) annotation will not be detected.
Bean definition has to be a concrete instance so use DefaultMyService instead of the interface. Spring will not detect anything for you your understanding is wrong
and 4. Will not change anything only adding dependencies without proper 1. or 2. will do nothing.
Just add a #Bean to your configuration
#Bean
public DefaultMyService myService() {
return new DefaultMyService();
}
Or import the other libraries applicatiponContext.xml which is what you probably should do.
#ImportResource("classpath:/applicationContext.xml")
Add this next to the #SpringBootApplication.

#Qualifier and #Resource doesn't work when running test case under Spring test framework

I have a test case which has a dependency of 'ticketDao', like below:
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
public class LfnSaleCancellationIntegrationTest extends BaseIntegrationTest {
//#Resource(name = "baseTicketDao")
private BaseTicketDao ticketDao;
....
public void setTicketDao(#Qualifier("baseTicketDao") BaseTicketDao ticketDao) {
this.ticketDao = ticketDao;
}
}
and BaseIntegrationTest extends from spring test framework's AbstractJpaTests, Spring is v3.0.5
When run this test case, I got a similar exception:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [com.mpos.lottery.te.gamespec.sale.dao.BaseTicketDao]
is defined: expected single matching bean but found 2:
[baseTicketDao, extraballTicketDao]
My project has evolved a long time, in fact when I encountered this exception at the first time, #Qualifier solved it. Till today this project has changed much, but I really have no idea why #Qaulifier and #Resource don't work any more.
And if i remove the dependency of 'ticketDao', the test case will pass. I am wondering whether there are some change of spring configuration cause this exception? or ... i have googled much, but seem no other people ever faced such a problem, pls give your comments, thanks very much!
You are using AbstractJPATests which is part of old spring test framework and (indirect) subclass of AbstractDependencyInjectionSpringContextTests. By default the injection is not annotation based but it discovers setters and fields and attempts injection by type. It would be recommended to switch to newer annotation based tests, refer to spring documentation for details.
As a workaround try to change autowire mode. Call it in test constructor as this.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME), rename your field to baseTicketDao and remove setter.
I knew the reason. In my new project, there are a statement of context:component-scan in spring configuration file, which will register 4 BeanPostProcessors by default:
AutowiredAnnotationBeanPostProcessor(#Autowired)
RequiredAnnotationBeanPostProcessor(#Require)
CommonAnnotationBeanPostProcessor(JSR-250 annotations, #Resource, #PostConstruct etc, #WebServiceRef )
PersistenceAnnotationBeanPostProcessor(#PersistenceUnit and #PersistenceContext)
While in my old project, only the default BeanPostProcessor(internalAutoProxyCreator) has been registered. My understanding is AutowiredAnnotationBeanPostProcessor will always wire by type. Anyway if remove context:component-scan, my test case can pass now.
In fact i have migrate all my test cases to spring test context framework now, and context:component-scan must be stated, otherwise #Autowired, #Resource etc annotation will be ignored, and you will get a great many of NullPointerException of those automaticaly injected dependencies.
NOTE: <context:annotation-config/> will register those 4 BeanPostProcessors too.

Annotation-specified bean name conflicts with existing, non-compatible bean def

I'm having a problem with some Spring bean definitions. I have a couple of context xml files that are being loaded by my main() method, and both of them contain almost exclusively a context:component-scan tag. When my main method starts up, I get this error from Spring:
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'converterDAO' for bean class [my.package.InMemoryConverterDaoImpl] conflicts with existing, non-compatible bean definition of same name and class [my.other.package.StaticConverterDAOImpl]
Both DAO classes are annotated this way:
#Repository("converterDAO")
public class StaticConverterDAOImpl implements ConverterDAO {
...
}
The in-memory dao also has the #Repository("converterDAO") annotation. The dao is referenced in other classes like this:
...
private #Autowired #Qualifier("converterDAO") ConverterDAO converterDAO;
...
I want one DAO to override the definition of the other one, which as I always understood it was one of the principal reasons to use a DI framework in the first place. I've been doing this with xml definitions for years and never had any problems. But not so with component scans and annotated bean definitions? And what does Spring mean when it says they are not "compatible"? They implement the same interface, and they are autowired into fields that are of that interface type. Why the heck are they not compatible?
Can someone provide me with a way for one annotated, component-scanned bean to override another?
I had a similar issue with Spring 4.x using #RestController. Two different packages had a class with the same name...
package com.x.catalog
#RestController
public class TextureController {
...
package com.x.cms
#RestController
public class TextureController {
...
The fix was easy...
package com.x.catalog
#RestController("CatalogTextureController")
public class TextureController {
...
package com.x.cms
#RestController("CMSTextureController")
public class TextureController {
...
The problem seems to be that the annotation gets autowired and takes the class name by default. Giving it an explicit name in the #RestController annotation allows you to keep the class names.
In an XML file, there is a sequence of declarations, and you may override a previous definition with a newer one. When you use annotations, there is no notion of before or after. All the beans are at the same level. You defined two beans with the same name, and Spring doesn't know which one it should choose.
Give them a different name (staticConverterDAO, inMemoryConverterDAO for example), create an alias in the Spring XML file (theConverterDAO for example), and use this alias when injecting the converter:
#Autowired #Qualifier("theConverterDAO")
I had a similar problem, with two jar libraries (app1 and app2) in one project. The bean "BeanName" is defined in app1 and is extended in app2 and the bean redefined with the same name.
In app1:
package com.foo.app1.pkg1;
#Component("BeanName")
public class Class1 { ... }
In app2:
package com.foo.app2.pkg2;
#Component("BeanName")
public class Class2 extends Class1 { ... }
This causes the ConflictingBeanDefinitionException exception in the loading of the applicationContext due to the same component bean name.
To solve this problem, in the Spring configuration file applicationContext.xml:
<context:component-scan base-package="com.foo.app2.pkg2"/>
<context:component-scan base-package="com.foo.app1.pkg1">
<context:exclude-filter type="assignable" expression="com.foo.app1.pkg1.Class1"/>
</context:component-scan>
So the Class1 is excluded to be automatically component-scanned and assigned to a bean, avoiding the name conflict.
I had a similar problem, and it was because one of my beans had been moved to another directory recently. I needed to do a "build clean" by deleting the build/classes/java directory and the problem went away. (The error message had the two different file paths conflicting with each other, although I knew one should not actually exist anymore.)
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.
I had the same issue. I solved it by using the following steps(Editor: IntelliJ):
View -> Tool Windows -> Maven Project. Opens your projects in a
sub-window.
Click on the arrow next to your project.
Click on the lifecycle.
Click on clean.
I also had a similar problem. I built the project again and the issue was resolved.
The reason is, there are already defined sequences for the Annotation-specified bean names, in a file. When we do a change on that bean name and try to run the application Spring cannot identify which one to pick. That is why it shows this error.
In my case, I removed the previous bean class from the project and added the same bean name to a new bean class. So Spring has the previous definition for the removed bean class in a file and that conflicts with the newly added class while compiling. So if you do a 'build clean', previous definitions for bean classes will be removed and compilation will success.
If none of the other answers fix your problem and it started occurring after change any configuration direct or indirectly (via git pull / merge / rebase) and your project is a Maven project:
mvn clean
Explanation internal working on this error
You are getting this error because after instantiation the container is trying to assign same object to both classes as class name is same irrespective of different packages......thats why error says non compatible bean definition of same name ..
Actually how it works internally is--->>>>.
pkg test1;
….
#RestController
class Test{}
pkg test2;
….
#RestController
class Test{}
First container will get class Test and #RestController indicates it to instantiate as…test = new Test(); and it won’t instantiate twice
After instantiating container will provide a reference variable test(same as class name) to both the classes and while it provide test reference
To second class it gets non compatible bean definition of same name ……
Solution—>>>>
Assign a refrence name to both rest controller so that container won’t instantiate with default name and instantiate saperately for both classes irrespective
Of same name
For example——>>>
pkg test1;
….
#RestController(“test1”)
class Test{}
pkg test2;
….
#RestController(“test2”)
class Test{}
Note:The same will work with #Controller,#Service,#Repository etc..
Note: if you are creating reference variable at class level then you can also annotate it with #Qualifier("specific refrence name") for example
#Autowired #Qualifier("test1")
Test test;
I had the same issue on IntelliJ after moving an existing file to a new package, solved cleaning caché, when trying to run with maven got that error. I managed solve it with:
cache:clean
Using Eclipse, I had moved classes into new packages, and was getting this error. What worked for me was doing:
Project > Clean
and also cleaning my TomCat server by right-clicking on it and selecting clean
Scenario:
I am working on a multi-module Gradle project.
Modules are:
- core,
- service,
- geo,
- report,
- util and
- some other modules.
So primarily we have prepared a Component[locationRecommendHttpClientBuilder] in geo module.
Java Code:
import org.springframework.stereotype.Component
#Component("locationRecommendHttpClientBuilder")
class LocationRecommendHttpClientBuilder extends PanaromaHttpClientBuilder {
#Override
PanaromaHttpClient buildFromConfiguration() {
this.setURL(PanaromaConf.getInstance().getString("locationrecommend.url"))
this.setMethod(PanaromaConf.getInstance().getString("locationrecommend.method"))
this.setProxyHost(PanaromaConf.getInstance().getString("locationrecommend.proxy.host"))
this.setProxyPort(PanaromaConf.getInstance().getInt("locationrecommend.proxy.port", 0))
return super.build()
}
}
application-context.xml
<bean id="locationRecommendHttpClient"
class="au.co.google.panaroma.platform.logic.impl.PanaromaHttpClient"
scope="singleton" factory-bean="locationRecommendHttpClientBuilder"
factory-method="buildFromConfiguration" />
Then it is decided to add this component in core module.
One engineer has previous code for geo module and then he has taken the latest module of core but he forgot to take the latest geo module.
So the component[locationRecommendHttpClientBuilder] is double times in his project and he was getting the following error.
Caused by:
org.springframework.context.annotation.ConflictingBeanDefinitionException:
Annotation-specified bean name 'LocationRecommendHttpClientBuilder'
for bean class
[au.co.google.app.locationrecommendation.builder.LocationRecommendHttpClientBuilder]
conflicts with existing, non-compatible bean definition of same name
and class
[au.co.google.panaroma.platform.logic.impl.locationRecommendHttpClientBuilder]
Solution Procedure:
After removal the component from geo module, component[locationRecommendHttpClientBuilder] is only available in core module. So there is no conflicting situation. Issue is solved by this way.
I faced this issue when I imported a two project in the workspace. It created a different jar somehow so we can delete the jars and the class files and build the project again to get the dependencies right.
In my case, issue was with pom.xml
I had dependency added in my application pom.xml for two different packages, which were reflecting to same class name.
Check your pom.xml or annotations which can be the possible injection point for same class.
if you build server with file jar and you use mvn clean install then you change branch with git you have to use command mvn clean either it throw exception as on the article.
key word: mvn clean
Refresh gradle project on Eclipse solved this problem for me

Resources