Spring Boot #SpringBootTest gives NoClassDefFoundError: ...DataAccessException - java

I'm unable to solve this. I have a spring boot application.
Main class annotated with
#SpringBootApplication.
Test class annotated with:
#RunWith(SpringRunner.class)
#SpringBootTest
Everything is fine until i add a filter-configurer class in the application:
#Configuration
public class YadaYadaFilterConfigurer
{
#Bean
public FilterRegistrationBean<YadaYadaFilter> createYadaYadaFilter()
{...}
...
}
Boom!
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.FilterRegistrationBean]:
...
nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:...org.springframework.boot/spring-boot-test-autoconfigure/2.0.6.RELEASE/b0eb15474e795850dfa59b01ee6a83d7a39e3645/spring-boot-test-autoconfigure-2.0.6.RELEASE.jar!/org/springframework/boot/test/autoconfigure/jdbc/JdbcTest.class]; nested exception is java.lang.NoClassDefFoundError: org/springframework/dao/DataAccessException
My dependencies:
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}
Some clearification.
Stripped so that I have only this test-class:
#RunWith(SpringRunner.class)
#SpringBootTest
public class JsonvalidationApplicationTests {
#Test
public void contextLoads() {
}
}
If comment out the #SpringBootTest then everything works. Seems like this annotation introduces a need for more dependencies?
Some more stacktrace:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.FilterRegistrationBean]: Factory method 'createyadayadaFilter' threw exception; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/C:/Users/66122872/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test-autoconfigure/2.0.6.RELEASE/b0eb15474e795850dfa59b01ee6a83d7a39e3645/spring-boot-test-autoconfigure-2.0.6.RELEASE.jar!/org/springframework/boot/test/autoconfigure/jdbc/JdbcTest.class]; nested exception is java.lang.NoClassDefFoundError: org/springframework/dao/DataAccessException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:583)
... 67 more
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/C:/Users/66122872/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test-autoconfigure/2.0.6.RELEASE/b0eb15474e795850dfa59b01ee6a83d7a39e3645/spring-boot-test-autoconfigure-2.0.6.RELEASE.jar!/org/springframework/boot/test/autoconfigure/jdbc/JdbcTest.class]; nested exception is java.lang.NoClassDefFoundError: org/springframework/dao/DataAccessException

Sorry, after some more investigation i found that the problem is in my FilterRegistrationBean.
the exeption is thrown here.
ClassPathScanningCandidateComponentProvider provider = createComponentScanner();
provider.findCandidateComponents("").stream()...
I will answer this thread and create a new.

Related

How to get properties from .env file in spring boot test

I am trying to setup tests for my spring-boot application. In regular execution I get some values from .env file that I've specified in run configuration and get them like so:
#Value("${jdbc.url}")
private String jdbcUrl;
But when I try to run the simplest of tests, it fails with the exception :
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext........
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'jdbc.url' in value "${jdbc.url}"
How do I load properties from the environment in SpringBootTest?
Here's my test:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {App.class})
public class TestingWebApplicationTest {
#Test
public void contextLoads() {
}
}
Try adding your property to this location /src/test/resources/application-test.properties
Add an #ActiveProfiles("test") annotation on the test class and it should be picked up.
See screenshot below;
You can use a profile specific application-{profile}.properties file

Spring Boot #Autowire not working. Error creating bean

Hi I have a spring boot project. The main class package is like this :
com.som.demo
I have used an external jar as a maven dependency in my project. In that jar there is a service class annotated with #Service as below :
#Service
public class SomeServiceImpl implements SomeService {
#Autowired
private TreeCacheWrapper ffCoreCache;
#Autowired(required = false)
private ZookeeperProperties zookeeperProperties;
public SomeServiceImpl(TreeCacheWrapper ffCoreCache, ZookeeperProperties zookeeperProperties) {
this.ffCoreCache = ffCoreCache;
this.zookeeperProperties = zookeeperProperties;
}
}
And the main package where this SomeServiceImpl class is as below :
com.som.test
Now in my project when I am autowiring the class I get the bean creation error while running the spring boot app. This is how I am doing :
#Autowired
private SomeService someService;
Error :
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'someServiceImpl'
Unsatisfied dependency expressed through field 'ffCoreCache';
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'ffCoreCache' defined in class path resource [com/som/test/config/ZooKeeperConfig.class]:
Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [com.som.test.cache.TreeCacheWrapper]:
Factory method 'ffCoreCache' threw exception;
nested exception is java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'ffCoreCache' defined in class path resource [com/som/test/config/ZooKeeperConfig.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [com.som.test.cache.TreeCacheWrapper]:
Factory method 'ffCoreCache' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.som.test.cache.TreeCacheWrapper]:
Factory method 'ffCoreCache' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: java.lang.ClassNotFoundException: org.apache.curator.retry.ExponentialBackoffRetry
When spring boot application starts, it scans for beans in the same package as your main class, and all packages beneath it.
Since your main class resides in the package com.som.demo spring boot will find any beans in this package, or in packages like com.som.demo.sample1, com.som.demo.a.b.c etc
However it won't scan com.som.test package because its a "peer" to the main package.
In general you can configure spring boot to scan the packages of your choice with the help of #ComponentScan annotation that accepts a list of base packages to scan. You can put this annotation right on your main class (next to #SpringBootApplication).
However this is kind of against the conventions of spring boot.
Read this tutorial for more technical details and examples.
Annotate Service interface with #Service, not the Implementation class and try to annotate ServiceImplementation class with #Component.
Spring boot by default scan to beans in your main package. you can configure it using
#SpringBootApplication(scanBasePackages={"com.som.demo" , "com.som.test"})

Spring Boot: ReactiveCrudRepository is not being implemented by any bean

I plan to use Cassandra to save data reactively. To do that, I wrote the following interface:
#Repository
public interface ContributorStatRepository extends ReactiveCrudRepository<ContributorStat, Long> {
Flux<ContributorStat> findByAkonId(String akonId);
}
The exception above is thrown:
com.example.sample.controller.ContributorStatControllerTest > shouldReturnBadRequestWithBlankContributorStat FAILED
java.lang.IllegalStateException
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException
Do you know why the appropiate bean for ContributorStatRepository is not being created?
I am using Spring boot 2.0.0.M7 and these dependencies:
dependencies {
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('javax.xml.bind:jaxb-api:2.3.0')
compile('org.springframework.boot:spring-boot-starter-webflux')
compile('org.springframework.boot:spring-boot-starter-data-cassandra-reactive')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('io.projectreactor:reactor-test')
}
Updated:
Running test:
#Test
public void shouldReturnBadRequestWithBlankContributorStat() throws Exception {
requestPayload = mapper.writeValueAsString(new ContributorStatDTO());
this.mockMvc.perform(post(CONTRIBUTOR_STATS_ROUTE)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(requestPayload)).andDo(print())
.andExpect(status().isBadRequest());
}
It seems you're using an #WebMvcTest annotated class to test this case (I'm not sure though, that part is missing from your question).
To test Spring WebFlux applications, you should use #WebFluxTest (see reference documentation). Even if you do, the ContributorStatRepository bean won't be there since the web test slice will only consider the web parts of your application and you usually need to mock this one with #MockBean.

Unable to use PowerMockito with PowerMockRunnerDelegate set as SpringJUnit4ClassRunner

I am trying to integrate PowerMockito with my spring boot unit test cases suite.
I am using consul to fetch my app configuration from the cloud.I am getting following exception while running junit testcases :
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.cloud.consul.config.ConsulConfigBootstrapConfiguration$ConsulPropertySourceConfiguration': Unsatisfied dependency expressed through field 'consul': Error creating bean with name 'consulClient' defined in org.springframework.cloud.consul.ConsulAutoConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ecwid.consul.v1.ConsulClient]: Factory method 'consulClient' threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.ecwid.consul.v1.ConsulRawClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consulClient' defined in org.springframework.cloud.consul.ConsulAutoConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ecwid.consul.v1.ConsulClient]: Factory method 'consulClient' threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.ecwid.consul.v1.ConsulRawClient
Following is my code:
#SpringBootApplication
#EnableRetry
#EnableDiscoveryClient
#EnableScheduling
#ConfigurationProperties(prefix = "scheduler")
class TestApplication{
}
#ActiveProfiles("abc")
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
#PrepareForTest(KafkaClientUtil.class)
#SpringApplicationConfiguration(classes=TestApplication.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ProcessorTest {
#Autowired
private TestClient Client;
#Test
public void test1() throws JsonProcessingException {
}
}

Can not apply DaoAuthenticationConfigurer to already built object

I'm getting this exception:
[WARN] org.springframework.web.context.support.GenericWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private io.ilopezluna.japanathome.service.UserService io.ilopezluna.japanathome.web.rest.AccountResource.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.crypto.password.PasswordEncoder io.ilopezluna.japanathome.service.UserService.passwordEncoder; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer#54aa5730 to already built object
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:293) ~[spring-beans-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) ~[spring-beans-4.0.7.RELEASE.jar:4.0.7.RELEASE]
You can see more on https://travis-ci.org/ilopezluna/japan-at-home/builds/37866955
This exception is thrown during my execution of tests. But I can't reproduce it on my localhost, I always get a build success :S
It took me two days, but I believe I've finally solved this. In my SecurityConfiguration class I had the following method:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(jsr250Enabled=true, prePostEnabled=true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(authenticationService);
}
}
I replaced the configureGlobal method with a configure method:
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(authenticationService);
}
And now everything works fine.
According to this answer the difference is that the using configureGlobal will allow the AuthenticationManager by global method security or another HttpSecurity (WebSecurityConfigurerAdapter).
As you can see above, I am enabling both Web Mvc Security and global method security. According to my unit tests, both continue to work with this change, but there is some debate here at my office on whether this change is correct (ie, if it is configuring global method security correctly), or if there is another problem with this solution.
We believe the root cause of the problem is some type of Spring bug, possibly a race condition. As unlikely as that seems, the problem only manifested itself when we added a empty class to the project, it didn't matter what the class's package or name was.

Categories