0

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 .

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.