预测试 SBT 任务:无法实例化 JDBC 驱动程序
Pre-test SBT task: Unable to instantiate JDBC driver
我在使用 Flyway 进行 SBT 任务 到 运行 迁移时遇到问题;当我 运行 任务时出现异常。有什么办法可以解决吗?
org.flywaydb.core.api.FlywayException: Unable to instantiate JDBC driver: org.postgresql.Driver => Check whether the jar file is present
以下代码有效,当我在 BeforeAll
中 运行 时,在我的 tests (ScalaTest) 中,但在我移动它时不起作用进入 SBT 任务。
val flyway = Flyway
.configure()
.locations("filesystem:./**/resources/db/migrations/")
.dataSource("jdbc:postgresql://localhost:5432/my_database", "my_user", "secret")
.load()
flyway.clean()
flyway.migrate()
我的 /build.sbt
文件如下所示:
import org.flywaydb.core.Flyway
lazy val migrate = taskKey[Unit]("Migrate database")
lazy val migrateTask = Def.task {
println("Migrate")
val flyway = Flyway
.configure()
.locations("filesystem:./**/resources/db/migrations/")
.dataSource("jdbc:postgresql://localhost:5432/my_database", "my_user", "secret")
.load()
flyway.clean()
flyway.migrate()
}
val IntegrationTest = config("integration") extend Test
lazy val integrationTestSettings = inConfig(IntegrationTest)(Defaults.testSettings) ++ List(
IntegrationTest / fork := false,
IntegrationTest / parallelExecution := false,
IntegrationTest / sourceDirectory := baseDirectory.value / "src/test/integration",
IntegrationTest / test := {
(IntegrationTest / test) dependsOn migrateTask
}.value
)
lazy val root = Project(id = "hello", base = file("."))
.configs(Configs.all: _*)
.settings(
integrationTestSettings,
libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.4",
)
我的 /project/build.sbt
看起来像这样:
libraryDependencies ++= List(
"org.flywaydb" % "flyway-core" % "7.6.0",
"org.postgresql" % "postgresql" % "42.2.19",
)
我使用的版本是:
- SBT: 1.4.5
- 斯卡拉:2.13.4
- 飞路:7.6.0
有人知道我为什么会收到这个错误吗?我该如何解决?
如有任何帮助,我们将不胜感激。谢谢:)
在 Flyway 存储库上搜索,错误消息来自此处 - https://github.com/flyway/flyway/blob/9033185ab8bfa56b0dae9136c04763cdccc50081/flyway-core/src/main/java/org/flywaydb/core/internal/jdbc/DriverDataSource.java#L165-L182 它正在尝试从类加载器加载数据库驱动程序。这些 ClassLoader 技术有时会与 sbt 将分层 ClassLoader 设置为 运行 sbt 本身发生冲突。这是我对正在发生的事情的猜测。
我们如何解决这个问题?
您说过 运行将其作为测试工作的一部分,因此也许您可以为此目的创建一个子项目?
ThisBuild / scalaVersion := "2.13.4"
lazy val migrate = taskKey[Unit]("Migrate database")
lazy val root = (project in file("."))
.settings(
name := "hello",
migrate := (migrateProj / run).toTask("").value
)
// utility project to run database migration
lazy val migrateProj = (project in file("migrate"))
.settings(
libraryDependencies ++= List(
"org.flywaydb" % "flyway-core" % "7.6.0",
"org.postgresql" % "postgresql" % "42.2.19",
),
Compile / run / fork := true,
publish / skip := true,
)
migrate/Migrate.scala
object Migrate extends App {
println("migrate")
// rest of the code here...
}
现在您可以运行
sbt:flyway> migrate
[info] running (fork) Migrate
[info] migrate
[success] Total time: 4 s, completed Mar 6, 2021 9:03:07 PM
关于分层类加载器的详细信息
ClassLoader 技术有时会与 sbt 将分层 ClassLoader 设置为 运行 sbt 本身发生冲突。 sbt
-the-Bash-脚本允许用户使用 project/build.properties
选择 sbt 版本,使用 build.sbt
选择 Scala 版本。这两者都使 sbt build 具有声明性和可重复性,通常是一件好事。但是,使用 Scala 2.10 编写的 sbt 启动器如何启动使用 Scala 2.12 编写的 sbt 1.4.x,然后启动您的 Scala 2.13 应用程序?这些边界的每一个交叉都是通过创建一个分层的ClassLoader来完成的,就像电影盗梦空间一样。
我在使用 Flyway 进行 SBT 任务 到 运行 迁移时遇到问题;当我 运行 任务时出现异常。有什么办法可以解决吗?
org.flywaydb.core.api.FlywayException: Unable to instantiate JDBC driver: org.postgresql.Driver => Check whether the jar file is present
以下代码有效,当我在 BeforeAll
中 运行 时,在我的 tests (ScalaTest) 中,但在我移动它时不起作用进入 SBT 任务。
val flyway = Flyway
.configure()
.locations("filesystem:./**/resources/db/migrations/")
.dataSource("jdbc:postgresql://localhost:5432/my_database", "my_user", "secret")
.load()
flyway.clean()
flyway.migrate()
我的 /build.sbt
文件如下所示:
import org.flywaydb.core.Flyway
lazy val migrate = taskKey[Unit]("Migrate database")
lazy val migrateTask = Def.task {
println("Migrate")
val flyway = Flyway
.configure()
.locations("filesystem:./**/resources/db/migrations/")
.dataSource("jdbc:postgresql://localhost:5432/my_database", "my_user", "secret")
.load()
flyway.clean()
flyway.migrate()
}
val IntegrationTest = config("integration") extend Test
lazy val integrationTestSettings = inConfig(IntegrationTest)(Defaults.testSettings) ++ List(
IntegrationTest / fork := false,
IntegrationTest / parallelExecution := false,
IntegrationTest / sourceDirectory := baseDirectory.value / "src/test/integration",
IntegrationTest / test := {
(IntegrationTest / test) dependsOn migrateTask
}.value
)
lazy val root = Project(id = "hello", base = file("."))
.configs(Configs.all: _*)
.settings(
integrationTestSettings,
libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.4",
)
我的 /project/build.sbt
看起来像这样:
libraryDependencies ++= List(
"org.flywaydb" % "flyway-core" % "7.6.0",
"org.postgresql" % "postgresql" % "42.2.19",
)
我使用的版本是:
- SBT: 1.4.5
- 斯卡拉:2.13.4
- 飞路:7.6.0
有人知道我为什么会收到这个错误吗?我该如何解决?
如有任何帮助,我们将不胜感激。谢谢:)
在 Flyway 存储库上搜索,错误消息来自此处 - https://github.com/flyway/flyway/blob/9033185ab8bfa56b0dae9136c04763cdccc50081/flyway-core/src/main/java/org/flywaydb/core/internal/jdbc/DriverDataSource.java#L165-L182 它正在尝试从类加载器加载数据库驱动程序。这些 ClassLoader 技术有时会与 sbt 将分层 ClassLoader 设置为 运行 sbt 本身发生冲突。这是我对正在发生的事情的猜测。
我们如何解决这个问题?
您说过 运行将其作为测试工作的一部分,因此也许您可以为此目的创建一个子项目?
ThisBuild / scalaVersion := "2.13.4"
lazy val migrate = taskKey[Unit]("Migrate database")
lazy val root = (project in file("."))
.settings(
name := "hello",
migrate := (migrateProj / run).toTask("").value
)
// utility project to run database migration
lazy val migrateProj = (project in file("migrate"))
.settings(
libraryDependencies ++= List(
"org.flywaydb" % "flyway-core" % "7.6.0",
"org.postgresql" % "postgresql" % "42.2.19",
),
Compile / run / fork := true,
publish / skip := true,
)
migrate/Migrate.scala
object Migrate extends App {
println("migrate")
// rest of the code here...
}
现在您可以运行
sbt:flyway> migrate
[info] running (fork) Migrate
[info] migrate
[success] Total time: 4 s, completed Mar 6, 2021 9:03:07 PM
关于分层类加载器的详细信息
ClassLoader 技术有时会与 sbt 将分层 ClassLoader 设置为 运行 sbt 本身发生冲突。 sbt
-the-Bash-脚本允许用户使用 project/build.properties
选择 sbt 版本,使用 build.sbt
选择 Scala 版本。这两者都使 sbt build 具有声明性和可重复性,通常是一件好事。但是,使用 Scala 2.10 编写的 sbt 启动器如何启动使用 Scala 2.12 编写的 sbt 1.4.x,然后启动您的 Scala 2.13 应用程序?这些边界的每一个交叉都是通过创建一个分层的ClassLoader来完成的,就像电影盗梦空间一样。