I am stuck with running JUnit tests. If I start my application with SpringApplication.class or with spring-boot:run - everything is ok. But when I am runnin JUnit tests - I am facing the error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 69 more
Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:229)
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.initializeDataSourceBuilder(DataSourceProperties.java:174)
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:42)
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat.dataSource(DataSourceConfiguration.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 70 more
I am sure that the error was not appearing before, but now I am stuck.
application.properties:
# Database
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/fileServer
spring.datasource.username=root
spring.datasource.password=
# JPA
spring.jpa.show_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--<scope>runtime</scope>-->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Test.class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {FileServerApplication.class})
public class FileServiceTest {
#Autowired
private FileService fileService;
#Autowired
private PathAppender pathAppender;
#Test
public void testCreateAndDeleteFile() {
String filename = "test.txt";
fileService.create(filename, FileType.FILE);
File file = new File(pathAppender.getUserDirectory() + filename);
assertTrue(file.exists());
fileService.delete(filename);
assertFalse(file.exists());
}
I've tried to play with mysql-connector scope but that does not take any effect.
Related
I try to implement the spring-boot project with mongoDB.
The mongoDB isn't installed locally - I use docker image for this task.
So:
docker run -d --name mongodb -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=pass -p 27017:27017
docker image installed successfully and I able to enter into docker shell with
docker exec -it {conteinerId} bash
Now, I try to execute spring-boot application.
application.properties:
spring.data.mongodb.database=proxy_db
spring.data.mongodb.host=localhost
spring.data.mongodb.username=root
spring.data.mongodb.password=pass
spring.data.mongodb.port=27017
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.task</groupId>
<artifactId>task</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>crud</name>
<description>User CRUD endpoints</description>
<properties>
<java.version>11</java.version>
<spring.boot.version>2.6.6</spring.boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring.boot.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</plugin>
</plugins>
</build>
</project>
After launching I received warning:
2023-01-30 19:53:41.941 WARN 12208 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
And as result, error:
APPLICATION FAILED TO START
Description:
Failed to configure a DataSource: 'url' attribute is not specified and
no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
As I understand - the spring can't establish the connection with the database.
So, how to correctly manage MongoDB in the spring-boot + docker?
You are using the wrong property names, eg url, hence "Failed to configure a DataSource: 'url' attribute is not specified."
Try these:
spring.datasource.url = mongodb://localhost:27017/proxy_db
spring.datasource.username = root
spring.datasource.password = password
Optionally you may need this:
spring.datasource.driver-class-name = com.mongodb.Mongo
Also there appear to be missing/incorrect dependencies:
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.11</version>
</dependency>
I'm using Spring Boot v2.6.2 and Java v17 and trying to test my MongoConnection without having a MongoDBService running because it should be tested with embedded in-memory MongoDB on the build machine, no need to set up an extra MongoDB service there.
For sure on the productive system, it should use a full MongoDB.
I try to get this easy example running:
#DataMongoTest
public class MongoTest
{
#Autowired
private UserRepository userRepository;
#AfterEach
void cleanUpDatabase()
{
this.userRepository.deleteAll();
}
#Test
void bootstrapTestDataWithMongoTemplate() {
final var restaurant = new User( "123", "ABC", "DEF" );
this.userRepository.insert( restaurant );
final var found = this.userRepository.findByFirstName( "ABC" );
System.out.println( found );
}
}
UserRepository is an interface that extends MongoRepository. User itself is just a DBEntity with #Document annotation. If I let the SpringBoot application run, not in test mode, everything works fine, because MongoDB is running at the specified location. But for the test, I want to let it run as an in-memory DB.
But Springboot wants to connect for the test.
2022-01-20 08:31:57.489 INFO 3976 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2022-01-20 08:31:57.521 INFO 3976 --- [localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-4.4.0.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:180) ~[mongodb-driver-core-4.4.0.jar:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:188) ~[mongodb-driver-core-4.4.0.jar:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:152) ~[mongodb-driver-core-4.4.0.jar:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.net.ConnectException: Connection refused: no further information
at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[na:na]
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:107) ~[mongodb-driver-core-4.4.0.jar:na]
at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:79) ~[mongodb-driver-core-4.4.0.jar:na]
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:65) ~[mongodb-driver-core-4.4.0.jar:na]
... 4 common frames omitted
Any suggestions on how to do this? Is #DataMongoTest testing in the wrong way? I thought the integrated flapdoodle dependency would inject it automatically in the test case.
The pom itself is also not that complex:
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.github.openjson</groupId>
<artifactId>openjson</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>com.github.erosb</groupId>
<artifactId>everit-json-schema</artifactId>
<version>1.14.0</version>
</dependency>
</dependencies>
The documentation states:
2.2.4. Embedded Mongo
Spring Boot offers auto-configuration for Embedded Mongo. To use it in
your Spring Boot application, add a dependency on
de.flapdoodle.embed:de.flapdoodle.embed.mongo and set the
spring.mongodb.embedded.version property to match the version of
MongoDB that your application will use in production. The default
download configuration allows access to most of the versions listed in
Embedded Mongo’s Version class as well as some others. Configuring an
inaccessible version will result in an error when attempting to
download the server. Such an error can be corrected by defining an
appropriately configured DownloadConfigBuilderCustomizer bean.
The port that Mongo listens on can be configured by setting the
spring.data.mongodb.port property. To use a randomly allocated free
port, use a value of 0. The MongoClient created by
MongoAutoConfiguration is automatically configured to use the randomly
allocated port. If you do not configure a custom port, the embedded
support uses a random port (rather than 27017) by default.
If you have SLF4J on the classpath, the output produced by Mongo is
automatically routed to a logger named
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo.
You can declare your own IMongodConfig and IRuntimeConfig beans to
take control of the Mongo instance’s configuration and logging
routing. The download configuration can be customized by declaring a
DownloadConfigBuilderCustomizer bean.
Therefore add the below dependency in scope:test if you want it to only be applied for Tests.
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
As well you need to set the version in your application.properties file:
spring.mongodb.embedded.version=4.0.21
https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.mongodb.embedded
Working Example:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.mongodb.embedded</groupId>
<artifactId>mongodb-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mongodb-app</name>
<description>Demo project for usage of embedded mongodb</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>test</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*IT.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
UserRepository:
public interface UserRepository extends MongoRepository<User, Long> {
//Spring converts this to Regex findByFirstnameRegex(String firstname) {"firstname" : {"$regex" : firstname }}
// automatically
public List<User> findByFirstName(String firstName);
}
User:
#Data
#Builder
public class User {
#Id
private Long id;
private String firstName;
private String lastName;
}
Test:
#DataMongoTest
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class UserControllerIT {
#Autowired
private UserRepository userRepository;
#BeforeAll
public void setup(){
userRepository.save(User.builder().id(1L).firstName("James").lastName("Bond").build());
userRepository.save(User.builder().id(2L).firstName("James").lastName("Farley").build());
userRepository.save(User.builder().id(3L).firstName("Marley").lastName("Hemp").build());
userRepository.save(User.builder().id(4L).firstName("James").lastName("Bond").build());
}
#Test
public void test_getById_successfull() throws Exception {
Assertions.assertEquals("James", userRepository.findByFirstName("James").get(0).getFirstName());
}
}
src/test/resources/application.properties
spring.data.mongodb.database=test
spring.data.mongodb.port=27017
spring.mongodb.embedded.version=4.0.2
Using liquibase and springboot , created db changelogs and able to run it successfully with maven-liquibase-plugin (mvn liquibase:update). I'm writing integration tests , in which liquibase changes needs to be created programmatically .
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = DummyApplication.class)
#ActiveProfiles("test")
public class TestDummyService
{
#Autowired
private SpringLiquibase springLiquibase;
...
#Test
public void testDummyRequest()
{
try {
Connection connection = springLiquibase.getDataSource().getConnection();
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
Liquibase liquibase = new liquibase.Liquibase("liquibase/changelog/db-changelog-master.xml", new ClassLoaderResourceAccessor(), database);
liquibase.update(new Contexts(springLiquibase.getContexts()), new LabelExpression(springLiquibase.getLabels()));
} catch (LiquibaseException | SQLException e) {
e.printStackTrace();
}
}
Getting the below exception while running the above test.
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [liquibase.integration.spring.SpringLiquibase]:
Factory method 'liquibase' threw exception; nested exception is java.lang.NoSuchMethodError: liquibase.integration.spring.SpringLiquibase.setLiquibaseSchema(Ljava/lang/String;)V
Caused by: java.lang.NoSuchMethodError: liquibase.integration.spring.SpringLiquibase.setLiquibaseSchema(Ljava/lang/String;)
below is application-test.property file .
#NOTE : spring.liquibase is the working one .
liquibase.changeLog=classpath:liquibase/changelog/db-changelog-master.xml
liquibase.enabled=true
liquibase.url=jdbc:h2:mem:cpass;DB_CLOSE_DELAY=-1
liquibase.user=root
liquibase.password=
spring.liquibase.dropFirst=true
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
jdbc.driverClassName=org.h2.Driver
spring.liquibase.enabled=true
spring.liquibase.change-log=classpath:liquibase/changelog/db-changelog-master.xml
#spring.liquibase.driver=com.mysql.jdbc.Driver
spring.liquibase.url=jdbc:mysql://localhost:3306/dummy
spring.liquibase.user=root
spring.liquibase.password=
**pom.xml : **
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.3.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.4.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.3.RELEASE</version>
</plugin>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<propertyFile>liquibase/liquibase.properties</propertyFile>
<changeLogFile>liquibase/changelog/db-changelog-master.xml</changeLogFile>
</configuration>
</plugin>
</plugins>
</build>
Is there anything Im missing in the test class or any sample project url is also much helpful . Im new to springboot and liquibase .
Spring Boot 2.1.3 depends on Liquibase 3.6.3, but you have specified 3.4.2 in your pom.xml.
Having said that, Spring Boot's Liquibase autoconfiguration will do everything you've written yourself in your unit test because you've already created the properties to activate the autoconfiguration. You could delete all of the code in the test method and just #Autowire a DataSource into the test class instead. Spring will apply the Liquibase changelog for you.
One last thing: if you can, it would be better to add a <parent> to your pom.xml which means you won't need to specify the individual versions of each dependency (including Liquibase). Spring Boot has a lot of dependencies and it's a lot of work keeping the versions in sync when you upgrade. This would also have prevented your NoSuchMethodError.
I have a following Spring boot project which uses Spring data JPA. My rest controller is annotated with the the following annotations-:
#SpringBootApplication
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
#ComponentScan({ "com.foo.bar"})
public class RESTService {
My question is why is the exclude parameter required in the #EnableAutoConfiguration ? If I start the application without the exclude I get the following exceptions-:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
Now I am manually configuring Hibernate from within my project.
My reasoning is that since Spring Boot sees spring data on the class path it tries to autoconfigure JDBC and Hibernate JPA. But then why isn't it trying to autoconfigure Mongo or any other data base solution ?
Can someone please help me to understand what is going on here ?
My POM file is-:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.bar</groupId>
<artifactId>Project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>REST Service</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.1.0</version>
</dependency>
<!--
<dependency>
<groupId>org.fosstrak.epcis</groupId>
<artifactId>epcis-repository</artifactId>
<version>0.5.0</version>
</dependency>
-->
<dependency>
<groupId>org.fosstrak.epcis</groupId>
<artifactId>epcis-repository</artifactId>
<version>0.5.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/epcis-commons-0.5.0.jar</systemPath>
</dependency>
</dependencies>
<properties>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.foo.bar.RESTService</mainClass>
<addResources>true</addResources>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Spring only autoconfigures Mongo if you have the respective starter dependency in your classpath.
For example:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
Regarding the Exception you postet, it says that you havn't configured your Databasedriver. You need someting along those lines in your properties:
spring.datasource.driver-class-name: oracle.jdbc.pool.OracleDataSource
spring.datasource.url: jdbc:oracle:thin:#<host>:1521:<schema>
spring.datasource.username: <user>
spring.datasource.password: <password>
Depending on what Database you use of course.
Based on your pom.xml I assume you are using Postgres. Make sure that in the application.properties file you configured your data source. Exception may suggest it is misconfigured.
spring.datasource.url=jdbc:postgresql://localhost/testdb
spring.datasource.username=postgres
spring.datasource.password=123
This question already has answers here:
Run Spring-boot's main using IDE
(9 answers)
Closed 6 years ago.
Edit:
Here's the WebApplication file:
#SpringBootApplication
#EnableAsync
#EnableAutoConfiguration
public class WebApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebApplication.class);
}
}
I am using IntelliJ(15.0.2) to run a spring boot project,
It is working properly when I execute java -jar spring-boot-sample.war
Unfortunately it failed to run by IDE and complained Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean
The error details are as follows:
[2016-07-25 12:32:46.979] boot - 5719 ERROR [restartedMain] --- SpringApplication: Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
at com.rentacoder.WebApplication.main(WebApplication.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:185)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:158)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
... 13 more
[2016-07-25 12:32:47.014] boot - 5719 INFO [restartedMain] --- ClasspathLoggingApplicationListener: Application failed to start with classpath: [file:/Users/hzhang/work/workplace/IdeaProjects/RHS/target/classes/]
Below is the dependencies settings in the POM file:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
Did I miss something in POM settings?
As a quick workaround, you can add a jar configuration that uses the resulting jar from target folder.
In this way you can start the application normally or in debug mode.
As a drawback for this approach: you won't have the hotswap available and you will see the changes only after a maven build. But in this case I usually add in the add jar run configuration window in before section a maven goal with "clean package -DskipTests" so each time I press run I will have the latest changes available.
This is a quickfix; the problem can be solved in other ways - I done it some times ago but I can't remember exactly what was the problematic dependency - you need to dig a little in Spring source code with some debugging around the methods from which the exception jumps.
How did you set the Configuration on IntelliJ? Since it's a WAR file, you'd need to have a web server container. Your pom has spring-boot-starter-tomcat, so you'll need to create a Tomcat Server configuration. This is a paid feature in IntelliJ, so you probably can't do it with the community edition.
A work-around is to create a Remote Debugging on your war file:
http://blog.trifork.com/2014/07/14/how-to-remotely-debug-application-running-on-tomcat-from-within-intellij-idea/