在IntelliJ IDEA中用Liquibase更新ScyllaDB Schema时遇类找不到异常
问题:Liquibase操作ScyllaDB时出现ClassNotFoundException及操作正确性确认
问题场景
使用Scala 2.13.1 + IntelliJ IDEA + Liquibase 4.5.0操作ScyllaDB的Schema迁移,相关配置及代码如下:
build.sbt(sbt 1.2.8)
ThisBuild / version := "0.1.0-SNAPSHOT" ThisBuild / scalaVersion := "2.13.1" lazy val root = (project in file(".")) .settings( name := "scylladb_liquibase" ) libraryDependencies ++= Seq( "org.liquibase" % "liquibase-core" % "4.5.0", "com.scylladb" % "scylla-driver-core" % "3.11.2.4" )
changelog.sql(根目录liquibase文件夹下)
--liquibase formatted sql --changeset zaryab:1 CREATE TABLE test01.TESTME1 ( foo int PRIMARY KEY, bar text ); --rollback DROP TABLE test01.TESTME1; --changeset zaryab:2 CREATE TABLE test01.TESTME2 ( foo int PRIMARY KEY, bar text ); --rollback DROP TABLE test01.TESTME2;
liquibase.properties(根目录liquibase文件夹下)
driver=com.scylladb.jdbc3.Driver classpath=scylla-driver-core-3.11.2.4.jar url=jdbc:scylla://172.17.0.2:9042/test01
主类LiquibaseExample.scala
import liquibase.Liquibase import liquibase.database.DatabaseFactory import liquibase.database.jvm.JdbcConnection import liquibase.resource.{ClassLoaderResourceAccessor, FileSystemResourceAccessor} import java.io.File import java.sql.DriverManager object LiquibaseExample { def main(args: Array[String]): Unit = { val props = new java.util.Properties() val fis = new java.io.FileInputStream(new File("liquibase/liquibase.properties")) props.load(fis) fis.close() val jdbcUrl = props.getProperty("url") val classpath = props.getProperty("classpath") Class.forName(classpath) val connection = DriverManager.getConnection(jdbcUrl) val database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection)) val liquibase = new Liquibase(props.getProperty("liquibase/changelog.sql"), new FileSystemResourceAccessor(), database) liquibase.update("") } }
运行时抛出异常:
[error] (run-main-0) java.lang.ClassNotFoundException: scylla-driver-core-3.11.2.4.jar [error] java.lang.ClassNotFoundException: scylla-driver-core-3.11.2.4.jar [error] at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476) [error] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588) [error] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) [error] at java.base/java.lang.Class.forName0(Native Method) [error] at java.base/java.lang.Class.forName(Class.java:315) [error] at LiquibaseExample$.main(LiquibaseExample.scala:37) [error] at LiquibaseExample.main(LiquibaseExample.scala) [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [error] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [error] at java.base/java.lang.reflect.Method.invoke(Method.java:566) [error] Nonzero exit code: 1 [error] (Compile / run) Nonzero exit code: 1
解决方案
1. 修复Class.forName参数错误
Class.forName()需要传入JDBC驱动的全限定类名,而非jar文件名。你错误地传入了scylla-driver-core-3.11.2.4.jar,正确值应为com.scylladb.jdbc3.Driver。另外JDBC 4.0+版本会自动加载驱动,可直接移除这行代码:
// 移除以下错误代码 // val classpath = props.getProperty("classpath") // Class.forName(classpath) // 直接获取数据库连接 val connection = DriverManager.getConnection(jdbcUrl)
2. 清理不必要的classpath配置
sbt已通过libraryDependencies引入ScyllaDB驱动,jar包会自动加入项目classpath,因此可删除liquibase.properties中的classpath=scylla-driver-core-3.11.2.4.jar配置项。
3. 修正Liquibase构造函数的changelog路径
代码中props.getProperty("liquibase/changelog.sql")是错误的,因为配置文件中无此键值。可直接传入文件路径,或在配置文件中新增配置后读取:
方式一:直接传入路径
val liquibase = new Liquibase("liquibase/changelog.sql", new FileSystemResourceAccessor(), database)
方式二:新增配置项读取
先修改liquibase.properties:
driver=com.scylladb.jdbc3.Driver url=jdbc:scylla://172.17.0.2:9042/test01 changelogFile=liquibase/changelog.sql
再修改代码:
val changelogPath = props.getProperty("changelogFile") val liquibase = new Liquibase(changelogPath, new FileSystemResourceAccessor(), database)
操作正确性确认
你的整体思路是正确的:
- 使用Liquibase的SQL格式changelog管理ScyllaDB Schema变更,符合工具最佳实践
- Changeset的作者、编号标记,以及rollback语句的配置均正确
- 依赖引入方式无误,仅需修正代码细节错误即可正常运行
内容的提问来源于stack exchange,提问作者Zaryab Ali
相关产品推荐
相关产品推荐

