我想将我的新项目升级到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;
}
答案 0 :(得分: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:这是Kotlin代码,但是您应该能够轻松地将其转换为Java。
答案 1 :(得分:1)
我为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");
}
}
}
答案 2 :(得分:1)
使用以下依赖项,即可解决此问题。
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.2.3</version>
</dependency>
答案 3 :(得分:0)
使用Javassist库,您可以检测FlywayDB库以记录不再受支持的Oracle版本,而不是引发致命异常(通过在try-catch子句中包装sureDatabaseIsCompatibleWithFlywayEdition方法调用)。以我为例,一旦我完成了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);
}
}