source

스프링 부트 2.1.0, 플라이웨이 4.2.0

itover 2023. 4. 2. 10:22
반응형

스프링 부트 2.1.0, 플라이웨이 4.2.0

새 프로젝트를 Spring Boot 버전 2.1.0으로 업그레이드하고 싶은데 Flyway 4.2.0 라이브러리에서 지원되는 Oracle 11 데이터베이스로 제한됩니다.Spring Boot 버전 2.0.5 릴리스에서는 모든 것이 정상적으로 동작하지만 2.1.0 릴리스로 이행하면 다음 오류가 발생합니다.

java.lang.NoClassDefFoundError: 
org/flywaydb/core/api/configuration/FluentConfiguration

POM 의 설정은 다음과 같습니다.

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.0.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>
    <ojdbc6.version>11.2.0.1</ojdbc6.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.oracle.jdbc</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>${ojdbc6.version}</version>
    </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>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
        <version>4.2.0</version>
    </dependency>
</dependencies>

갱신하다

@Configuration(또는 메인클래스에 추가)을 통해 문제를 해결할 수 있지만, 문제는 버그나 기능입니까?2.1.0 이전 버전에서는 모든 것이 자동 구성을 통해 수행되었으며 즉시 사용할 수 있습니다.

@Bean(initMethod = "migrate")
Flyway flyway() {
    Flyway flyway = new Flyway();
    flyway.setBaselineOnMigrate(true);
    flyway.setDataSource("jdbc:oracle:thin:@localhost:1521:xe", "USER", "PASSWORD1");
    return flyway;
}

나도 Postgre에 대해 같은 문제가 있었다.SQL 9.2 및 다음 클래스를 사용하여 문제를 해결했습니다.

단, Spring Boot 속성에서 설정할 수 있는 모든 커스텀 속성은 무시됩니다.이는 Flyway 자동 설정 전체를 사용자가 직접 대체하기 때문입니다.따라서 필요에 따라 코드를 추가해야 할 수 있습니다.

@Configuration
class FlywayConfig {
    @Bean
    fun flyway(dataSource: DataSource): Flyway {
        val flyway = Flyway()
        flyway.dataSource = dataSource
        return flyway
    }

    @Bean
    fun flywayInitializer(flyway: Flyway): FlywayMigrationInitializer {
        return FlywayMigrationInitializer(flyway, null)
    }

    /**
     * Additional configuration to ensure that [EntityManagerFactory] beans depend on the
     * `flywayInitializer` bean.
     */
    @Configuration
    class FlywayInitializerJpaDependencyConfiguration : EntityManagerFactoryDependsOnPostProcessor("flywayInitializer")
}

PS: 이것은 Kotlin 코드입니다만, Java로 간단하게 변환할 수 있을 것입니다.

다음과 같은 종속성을 사용하면 해결됩니다.

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>5.2.3</version>
</dependency>

Spring Boot 2.1.1을 설정하고 bean FlywayDefaultDdlModeProvider도 다시 정의해야 했습니다.

@Configuration
@ConditionalOnProperty(prefix = "spring.flyway", name = "enabled", matchIfMissing = true)
public class LegacyFlywayAutoConfiguration {

    @Bean
    @Primary
    public SchemaManagementProvider flywayDefaultDdlModeProvider(ObjectProvider<Flyway> flyways) {
        return new SchemaManagementProvider() {
            @Override
            public SchemaManagement getSchemaManagement(DataSource dataSource) {
                return SchemaManagement.MANAGED;
            }
        };
    }

    @Bean(initMethod = "migrate")
    public Flyway flyway(DataSource dataSource) {
        Flyway flyway = new Flyway();
        flyway.setBaselineOnMigrate(true);
        flyway.setDataSource(dataSource);
        return flyway;
    }

    @Bean
    public FlywayMigrationInitializer flywayInitializer(Flyway flyway) {
        return new FlywayMigrationInitializer(flyway, null);
    }

    /**
     * Additional configuration to ensure that {@link JdbcOperations} beans depend
     * on the {@code flywayInitializer} bean.
     */
    @Configuration
    @ConditionalOnClass(JdbcOperations.class)
    @ConditionalOnBean(JdbcOperations.class)
    protected static class FlywayInitializerJdbcOperationsDependencyConfiguration
            extends JdbcOperationsDependsOnPostProcessor {

        public FlywayInitializerJdbcOperationsDependencyConfiguration() {
            super("flywayInitializer");
        }

    }
}

Javassist 라이브러리를 사용하여 Flyway를 계측할 수 있습니다.치명적인 예외(sureDatabaseIsCompatible)를 발생시키는 대신 Oracle 버전이 더 이상 지원되지 않음을 기록하기 위한 DB 라이브러리WithFlywayEdition 메서드가 try-catch 절에서 호출됩니다).저 같은 경우에는 플라이웨이DB 커뮤니티 에디션(5.2.4)은 Oracle 11.2에서 정상적으로 동작하는 것 같습니다.이 솔루션에는 단점도 있지만, 제 경우 가장 좋은 옵션이었기 때문에(데이터베이스는 곧 업그레이드될 것입니다) 누군가도 유용하다고 생각할 수 있습니다.이상적으로는 다음 코드를 어플리케이션에서 실행해야 합니다.본인 부담으로 사용하세요.

public static void suppressIncompatibleDatabaseVersionCheck() {
    try {
        CtClass ctClass = ClassPool.getDefault().get("org.flywaydb.core.internal.database.base.Database");
        ctClass.defrost();
        CtMethod method = ctClass.getDeclaredMethod("ensureDatabaseIsCompatibleWithFlywayEdition");
        CtClass etype = ClassPool.getDefault().get("java.lang.Exception");
        method.addCatch("{ LOG.warn(\"Exception suppressed: \" + $e); return ;}", etype);
        ctClass.toClass();
    } catch (NotFoundException | CannotCompileException e) {
        log.error("Could not instrument FlywayDB code.", e);
    }
}

언급URL : https://stackoverflow.com/questions/53343506/spring-boot-2-1-0-with-flyway-4-2-0

반응형