When running tests in a spring boot based application, spring is unable to create the datasource bean:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
Reading this error it is clear to me, I think, that spring did not read my application.properties file located at:
src/test/resources/application.properties
For clairity, I do not want to make use of an in memory database when running my integration tests, for application specific reasons.
This file contains:
spring.datasource.url=jdbc:mysql://127.0.2.1:3306/project-test
spring.datasource.username=foo
spring.datasource.password=bar
spring.datasource.driverClassName=org.mariadb.jdbc.Driver
While when starting the application using bootRun at does read out
src/main/resources/application.properties
and does create the datasource correctly.
My tests are based on cucumber and started using the following class:
#RunWith(Cucumber.class)
public class AcceptanceTests {
}
The test context is started using the following annotations on a BaseSteps class which each class defining cucumber tests inherits from
#WebAppConfiguration
#ContextConfiguration(classes = App.class)
The spring context is started successfuly but it was unable to find my application.properties file and/or use it.
I found the solution.
I added changed the ContextConfiguration like so:
#ContextConfiguration(classes = App.class, loader = SpringApplicationContextLoader.class)
Use #SpringApplicationConfiguration instead of ContextConfiguration. This is needed for Spring-boot application tests.
Related
I am writing a Spring Boot integration test. Here I want to exclude several beans. So I am trying to load only as many beans as are required for my tests. For that I am using #COntextConfiguration and specifying only those classes which I want.
Despite of doing this I can see Spring Boot is still loading all other beans. Like for e.g it is loading RetryTemplateConfig which is present in a different package altogether. I used #ComponentScan to scan only current package and not the one in which RetryTemplateConfig lies. Still I get bean configuration errors. Below is my top section of my test class
#SpringBootTest
#RunWith(SpringJUnit4ClassRunner.class)
#Import(BulkExceptionClosureTestConfig.class)
#ActiveProfiles("test")
#TestPropertySource(locations = "classpath:application-test.yml", properties = {"INSTANCE_ID=1","spring.profiles.active=test","ENV=test"})
#ContextConfiguration(classes = {BulkExceptionClosureApplication.class, ClosureRequestCsvFileProcessor.class,
MetadataFetcher.class, XmlProcessingService.class})
#ComponentScan(basePackages = "com.barclays.exceptionclosure")
public class BulkExceptionClosureTest {
And I get below error when starting this test.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'retryTemplate' defined in class path resource [com/xyz/validation/config/RetryTemplateConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException
I have not included this class in my ContextConfiguration, still it gets loaded. Also #ComponentScan doesn't seem to work, as RetryTemplateConfig is in com.xyz.validation package. And my test class is in com.xyz.exceptionclosure package
What can be done to definitely load only the required beans for my test? Please not I cannot add #Profile("!test") on classes which I don;t want in Spring Boot integration test. Those are from library I cannot modify.
When trying to create a Spring Boot Java application with ActiveMQ Artemis I get the following exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'artemisConfiguration' defined in class path resource [org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedServerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.activemq.artemis.core.config.Configuration]: Factory method 'artemisConfiguration' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/activemq/artemis/api/core/QueueConfiguration
From the above exception I have difficult to understand what config might be missing or is it something else? I am using Spring Boot 2.7.3.
It is implemented to the letter as described in the this guide (native and embedded).
The fundamental problem is this:
java.lang.NoClassDefFoundError: org/apache/activemq/artemis/api/core/QueueConfiguration
This means that the JVM can't find this class. This class is in the artemis-commons module. You need to put this on your application's classpath.
I have a Java EE application with WildFly, and I use:
#Resource(lookup = "java:/jms/queue/MyQueue")
but now I am migrating part of this application to Spring one, and I have no idea how to look up for my JNDI resource.
In application.yaml I added:
spring:
datasource:
jndi-name: "java:jms/queue/MyQueue"
but it throws an error during startup:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRoute': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'java:/jms/queue/MyQueue' defined in JNDI environment: JNDI lookup failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or in an application resource file: java.naming.factory.initial
MyRoute.java:
#Resource(lookup = "java:/jms/queue/MyQueue")
private Queue queue1;
Is it possible to easily inject the resource in Spring?
I wish it can work like #Autowired does. Inject the Queue with lookup into JNDI.
I have one test class with #TestConfiguation and inside that a bean is returned as "headerProcessor".
Now that same bean I am importing and #autowiring in the class. Now if I run this class it is working fine. I am running the test class as Spring runner
But if I run another test class getting error like "Failed to load ApplicationContext" caused by UnsatisfiedDependencyException for bean "headerProcessor".
Sorry I cannot paste the codes its restricted from the company.
I can not start web app in eclipse embedded tomcat, but if I deploy war file in standalone tomcat then it works.
The exception I get is:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name defined in class path resource Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Factory method threw exception; nested exception is java.lang.NoClassDefFoundError: org/mockito/Mockito
The file exception is referring to is annotated with #Configuration and is located in src/test/java;
purpose of the file is to create mock beans for test cases.
The fix to the problem is this link:
How to prevent eclipse from deploying test classes on Tomcat?
The cause of the problem was, when eclipse was assembling a war file it would include src/test/java dir in it, and the dependencies were missing for test cases.
because in pom dependencies for test had test which means that maven will not include those jar files in final bucked product meaning war file.