当前位置: 首页 > 知识库问答 >
问题:

DriverManager在gradle自定义插件的任务中看不到依赖项

师承弼
2023-03-14

我正在写一些gradle插件,现在我遇到了一个问题,DriverManager看不到buildscript依赖项中定义的JDBC驱动程序:

我有下一个build.gradle文件:

buildscript {
   repositories {
      mavenCentral()
   }
   dependencies {
      classpath("com.h2database:h2:1.4.196")
   }
}
plugins {
   id "someplugin"
}
apply plugin: 'groovy'

当我调用扩展DefaultTask的任务中定义的命令时

DriverManager.getConnection("jdbc:h2:mem:", "sa", "")
No suitable driver found for jdbc:h2:mem:

共有1个答案

万俟渝
2023-03-14

那么,关于drivermanager为什么不像您使用它那样工作,以及如何使它工作,还有关于如何正确使用来自Groovy的SQL(这是Gradle脚本的基础)的问题,有了一个答案。我将从使用Groovy中的SQL的正确方法开始:

正确使用来自Gradle/Groovy的SQL:

将驱动程序添加到buildscript类路径是不够的不幸的是使用Groovy Sql类,您需要将驱动程序添加到正确的类加载器,否则它将无法正常工作。

configurathtml" target="_blank">ions { jdbc }
jdbc 'com.h2database:h2:1.4.196'
def sqlClassLoader = Sql.classLoader
configurations.jdbc.each { sqlClassLoader.addURL it.toURI().toURL() }
Sql.withInstance('jdbc:h2:mem:', 'sa', '', 'org.h2.Driver') {
    it.execute 'your sql here'
}

正确使用DriverManager:

由于Groovy的动态性,您不能像以前那样正确地使用drivermanager。在您使用的方法中,DriverManager尝试从callstack中动态查找调用方类,然后使用该类的classloader查找数据库驱动程序。对于Groovy,这是一个可以找到的动态代理类,因此在其类加载器中找不到数据库驱动程序。

如果您相反地为DriverManager显式地赋予适当的调用方类,如DriverManager.GetConnection(“jdbc:h2:mem:”,[user:“sa”,password:“”]作为属性,getClass()),它可以正常工作。或者,也可以不给任何调用方类,如drivermanager.getConnection(“jdbc:h2:mem:”,[user:“sa”,password:“”]as Properties,null),在这种情况下使用当前线程上下文类加载器,这也很好。

Gradle中自动驱动程序查找的问题:

当类DriverManager加载时,它会扫描系统属性jdbc.drivers以及提供java.sql.driver服务的所有服务。它遍历找到的类并实例化它们。驱动程序本身通常响应于向drivermanager注册自己,此时可以这样做,以便以后自动查找,就像我上面建议的那样。

现在的问题是,如果您正在使用Gradle守护进程(现在是默认的),并且在该守护进程中运行任何加载drivermanager的构建(例如,在您以前的tries中),则该类已经加载。如果稍后将buildscript依赖项添加到H2(或者在不存在buildscript依赖项但已加载DriverManager的构建项之后运行存在buildscript依赖项的构建项),则该类已经加载,并且不查找当前在类路径中的驱动程序。

  • 为您的构建禁用后台进程,并确保使用您的构建的人都不启用该后台进程。这很难控制和执行,会降低生成性能
  • 在调用GetConnection之前,请使用私有方法DriverManager.LoadInitialDrivers(),以确保再次执行查找并自动添加H2驱动程序。更好,但使用私有方法。
  • 使用ServiceLoader自己加载类路径中的所有Driver类,以使它们在GetConnection调用之前向DriverManager自我注册,如ServiceLoader.load(driver.class).Collection()。可能是最优雅的解决方案。

下面是显式命名驱动程序类的一些可能的变通方法:

  • 在使用getConnection()使其自我注册到org.h2.driver.ToString()
  • 之前,只需加载类
  • 只需加载类,然后使用GetConnection()使其自动注册到class.forName“org.h2.driver”
 类似资料:
  • 我正在尝试创建一个自定义任务/插件(两者都拒绝工作),用于我的gradle构建脚本。 我正在使用groovy插件,希望在单独的文件中声明任务/插件,而不是在我的构建中。格拉德尔。 我的项目树如下所示: 我试图做的是在中创建我的任务/插件类,然后在。 让我举一个小例子。 TestTask。groovy: build.gradle 当我尝试使用我的gradle.build(清洁,构建等)做任何事情时,

  • 在另一个项目中,我使用/应用这个插件: 但是如何从MyGradlePlugin.groovy中的apply方法中迭代公共依赖项并打印它们的坐标(artifactId、groupId、version)?

  • 如何编写自定义gradle插件来处理自定义存储库中自定义模块描述符中的依赖关系?gradle文档说了以下内容,但我还没有找到任何可以告诉我如何操作的内容。 即使您的项目使用的是自定义依赖关系管理系统或类似Eclipse的东西。类路径文件作为依赖关系管理的主数据,编写Gradle插件以在Gradle中使用此数据非常容易。 我一直在为ATG项目维护一个定制的常春藤解析器(源自此项目),但Gradle最

  • 我试图为其他gradle项目使用的自定义gradle插件构建一个jar。我使用java编写插件。我有一个问题,包括我的jar中的依赖项。如果我使用下面的代码构建jarbuild.gradle 在一个项目中应用插件时,我得到了一个针对guava类的NoClassDefFound异常。如果我在 它表示未找到Id为“my Plugin”的。如何在gradle插件jar中包含依赖项?

  • 问题内容: 我的公司最近写了gradle插件来进行原始配置(存储库,项目间的通用依赖关系等)。总体而言,这大大简化了我们的构建过程,并发现了项目之间的一些不一致之处。我们最近尝试向插件添加任务,但该任务无法正常工作。 这是坏掉的插件: 除了之外,此插件都很好用。当我将其添加到混合中(并编译/部署到我们的本地仓库)时,当我尝试构建使用插件的项目时出现此错误: 问题答案: 在脚本中定义任务时,将调用方