Spring Boot 2.1.0 с Flyway 4.2.0
Я хотел бы обновить мои новые проекты до Spring Boot версии 2.1.0, но я ограничен базой данных Oracle 11, которая поддерживается библиотекой Flyway 4.2.0. Все работает нормально в Spring Boot версии 2.0.5 Release, но при переходе к версии 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;
}
Ответы
Ответ 1
У меня была такая же проблема с PostgreSQL 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: это код Котлина, но вы должны легко перевести его на Java.
Ответ 2
Я сделал конфигурацию Spring Spring 2.1.1 и должен был переопределить компонент 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");
}
}
}
Ответ 3
Используя библиотеку Javassist, вы можете использовать библиотеку FlywayDB для регистрации того, что версия Oracle больше не поддерживается, вместо того, чтобы генерировать фатальное исключение (заключая вызов метода sureDatabaseIsCompatibleWithFlywayEdition в предложение try-catch). В моем случае редакция сообщества FlywayDB (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);
}
}
Ответ 4
Я согласен с вышеуказанными решениями. Но почему бы не перейти на последнюю зависимость от пролетного пути?
<!-- https://mvnrepository.com/artifact/org.flywaydb/flyway-core -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.2.4</version>
</dependency>
Это решит вашу проблему, так как FluentConfiguration является частью последней библиотеки от flyway-core.
Ответ 5
Используйте следующую зависимость, она будет разрешена этим.
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.2.3</version>
</dependency>