#EnableAutoConfiguration(exclude =...) on tests failed in Spring Boot 2.6.0 - spring

I tried to upgrade my data-mongo example project to Spring Boot 2.6.0. There is a test designed to run against Testcontainers, I also included the embedded mongo dep for other tests, so I have to exclude the AutoConfiguration for embedded mongo to make sure this test working on Docker/testcontainers.
The following configuration worked well with Spring Boot 2.5.6.
#DataMongoTest
#ContextConfiguration(initializers = {MongodbContainerInitializer.class})
#EnableAutoConfiguration(exclude = EmbeddedMongoAutoConfiguration.class)
#Slf4j
#ActiveProfiles("test")
public class PostRepositoryTest {}
But after upgrading to Spring Boot 2.6.0 and running the application, I got the exception like this.
[ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: o
rg.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'embeddedMongoServer' defined in class path resource [org/springframework/boot/autoconfig
ure/mongo/embedded/EmbeddedMongoAutoConfiguration.class]: Unsatisfied dependency expressed through method 'embeddedMongoServer' parameter 0; nested exception is org.springframework.bea
ns.factory.BeanCreationException: Error creating bean with name 'embeddedMongoConfiguration' defined in class path resource [org/springframework/boot/autoconfigure/mongo/embedded/Embed
dedMongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.flap
doodle.embed.mongo.config.MongodConfig]: Factory method 'embeddedMongoConfiguration' threw exception; nested exception is java.lang.IllegalStateException: Set the spring.mongodb.embedd
ed.version property or define your own MongodConfig bean to use embedded MongoDB
Obviously, #EnableAutoConfiguration(exclude =...) did not affect the context in tests when upgrading to Spring Boot 2.6.0.
Update: Temporarily resolved it, see my answer below.

Just add:
#TestPropertySource(properties = "spring.mongodb.embedded.version=3.5.5")
annotation before your Unit Test and it will start working.
#Henning's answer has a good explanation of why you need this.

As of Spring Boot 2.6, the property spring.mongodb.embedded.version must be set to use the auto-configured embedded MongoDB. It's mentioned in the release notes: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#embedded-mongo
This is also what the error message you posted, advises to do: Set the spring.mongodb.embedd ed.version property or define your own MongodConfig bean to use embedded MongoDB
The annotation #DataMongoTest is meta-annotated with #ImportAutoConfiguration and #AutoConfigureDataMongo, and is designed to trigger auto-configuration of MongoDB unless explicitly disabled as you do in the working configuration examples.
In your first configuration example, the annotation #EnableAutoConfiguration(exclude = EmbeddedMongoAutoConfiguration.class) does not override this effect of #DataMongoTest.
With Spring Boot 2.5.6, the auto-configured MongodConfig bean is most likely also part of the application context but not effectively used. But this depends on the rest of the code and in particular on the MongodbContainerInitializer.

Use #ImportAutoConfiguration(exclude = ...) or #DataMongoTest(excludeAutoConfiguration = ...) on test classes to overcome this barrier when upgrading to Spring Boot 2.6.0.
#DataMongoTest
#ImportAutoConfiguration(exclude = EmbeddedMongoAutoConfiguration.class)
//other config are ommitted
public class PostRepositoryTest {}
//or
#DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
public class PostRepositoryTest {}

Related

Error with Spring security framework 2.6.4 (NoSuchMethodError for getInterfaceMethodIfPossible)

After the update to Spring boot 2.6.4, I get this error while i try to call my rest controllers:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChainProxySecurityConfigurer' parameter 1; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is java.lang.NoSuchMethodError: 'java.lang.reflect.Method org.springframework.util.ClassUtils.getInterfaceMethodIfPossible(java.lang.reflect.Method, java.lang.Class)'
The problem does not occur until 2.6.3
I tried to add:
#EnableWebSecurity
#EnableWebMvc
To my WebSecurityConfigurerAdapter class, but that produces no difference
Spring Boot 2.6.4 should be used with Spring Framework 5.3.16 but you are using an earlier version. You need to update your Maven or Gradle configuration to correct this. I’d recommend using Spring Boot’s dependency management to keep versions in sync.
Upgrading spring-core version to 5.3.16 solved this issue.

How to resove java.lang.IllegalArgumentException: Property 'dataSource' in Junit for Springboot Rest

The error is thrown while trying to unit test the Service class that contains an autowired Dao object which internally uses an Autowired JdbcTemplate in Spring boot Rest service using Junit and Mockito
in you `SpringBootTest you should pass config classes or properties files where all configs are.
Probably dataSource is missing
#SpringBootTest(classes = YouAppRunnerOrConfig.class, properties = "...")

Spring Boot + Spring Integration Java DSL + AOP : Fails to proxy the Gateway interface

Hi I have a spring boot application, which starts a spring integration flow, through a gateway interface, using Java DSL. Everything works fine on its own. I added AOP to capture exceptions, with #EnableAspectJAutoProxy(proxyTargetClass = true)
At this stage, it gives the error:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jobInitiator': Post-processing of
FactoryBean's singleton object failed; nested exception is
org.springframework.aop.framework.AopConfigException: Could not
generate CGLIB subclass of class [class com.sun.proxy.$Proxy54]:
Common causes of this problem include using a final class or a
non-visible class; nested exception is
java.lang.IllegalArgumentException: Cannot subclass final class class
com.sun.proxy.$Proxy54
When I remove the proxyTargetClass = true, it works but the advices are not triggered.
Any help? Is there a way to start the spring integration flow without a gateway?
There is no class associated with the gateway Proxy so you can't advise it.
Is there a way to start the spring integration flow without a gateway?
Instead of using the gateway, declare a bean of type MessagingTemplate and use template.sendAndReceive(someMessage) or template.convertSendAndReceive(somePojo) instead. See here.
(The gateway uses a MessagingTemplate internally; the gateway unwraps a MessagingException and throws the cause, the template does not).
It also does not support an error channel.
To get closer to the gateway functionality, you can subclass MessagingGatewaySupport and invoke its sendAndReceive() method(s).

Disabling Transaction Management in Spring JMS listener

I have a spring boot application as a Spring JMS listener. i have configured multiple datasource manager one for Oracle and another one for DB2 .
whenever i am starting app ,jms listener container is looking for a transaction manager bean and giving below error as it find two bean.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jms.JmsAnnotationDrivenConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.transaction.PlatformTransactionManager org.springframework.boot.autoconfigure.jms.JmsAnnotationDrivenConfiguration.transactionManager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: db2TransactionManager,oracleTransactionManager
i dont want to maintain JMS transaction. how could i achieve it or how can we disable jms transaction feature?
below are the annotation i have added on my main spring boot class. also i am using Spring Data repository
#SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class})
#ComponentScan(basePackages = "com.deere.oracledataupdate.*")
//#EnableJpaRepositories(basePackages ="com.deere.oracledataupdate.dao.springdata")
#EntityScan(basePackages = "com.deere.oracledataupdate.*")
#PropertySource({ "classpath:application-${IafConfigSuffix}.properties" })
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Looking to the current Spring Boot code we have (JmsAnnotationDrivenConfiguration):
#Autowired(required = false)
private JtaTransactionManager transactionManager;
So, right now it requires only the bean which is exactly JtaTransactionManager by type. I guess both yours are DataSourceTransactionManager.
I'm sure that was correct fix to worry only about the XA tx-manager for auto-config.
Seems for me you can fix your issue with something like #Primary on one of your tx-manager beans.
But... Do you need a JMS Annotation support in your application at all?
Maybe it would be just enough to exclude JmsAnnotationDrivenConfiguration as well?
If need it anyway, I see only one way to fix it: disable JmsAnnotationDrivenConfiguration and configure #EnableJms manually, bypassing the tx-manager issue and just don't configure it for the DefaultJmsListenerContainerFactory as you request.
See JmsAnnotationDrivenConfiguration source code for more information.

Mockito Spring 3.1 Integration

I have been using #Configuration support in Spring to create my Mockito Mocks for use in JUnit tests
#Configuration
public class MockAppContextHelper {
#Bean
public IntegrationServerServiceWrapper integrationServerServiceWrapperTest() {
return mock(IntegrationServerServiceWrapper.class);
}
}
This used to work fine in Spring 3.0.2.
In Spring 3.1 I get the following error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'integrationServerServiceWrapperTest' defined in class path resource [com/kn/bpa/task/service/impl/MockAppContextHelper.class]: No matching factory method found: factory bean 'mockAppContextHelper'; factory method 'integrationServerServiceWrapperTest()'. Check that a method with the specified name exists and that it is non-static.
Any ideas?
Thanks for your support
Consider adding a reproduction project per the instructions at https://github.com/SpringSource/spring-framework-issues#readme that demonstrates the configuration in question working in 3.0.2 and failing against 3.1.x

Resources