【问题标题】:Java: No suitable driver found for jdbc:h2Java:找不到适合 jdbc:h2 的驱动程序
【发布时间】:2012-10-06 20:59:38
【问题描述】:

我的一些代码有问题,我已经搜索并尝试了我所知道的一切,但没有任何运气。


场景:

  • 应用程序检查 JDBC 驱动程序是否存在,在本例中为 H2 驱动程序 (org.h2.Driver)。
  • 如果它不存在,应用程序会下载 JDBC 驱动程序并将其添加到 ClassLoader,如下所示:(注意:storageDataManager 是我用于 SQL 方法的一个类)

       File h2Driver = new File(directory.toString() + File.separator + "lib" + File.separator + "h2.jar");
       if (h2Driver.exists()) {
           URL[] url = new URL[0];
           try {
               url = new URL[]{h2Driver.toURI().toURL()};
               storageDataManager.setClassLoader(new URLClassLoader(url));
           } catch (MalformedURLException ignore) {}
        }
    

当 storageDataManager 运行第一个查询时,它会尝试连接指定的驱动程序,如果它确实有 ClassLoader,它会使用 ClassLoader 代替:

if (getClassLoader() != null) {
    getLogging().debug("Loading custom class loader for H2 driver: " + getClassLoader().toString());
    Driver driver = (Driver) Class.forName("org.h2.Driver", true, getClassLoader()).newInstance();
    getLogging().debug("Loaded H2 driver: " + driver.toString() + " - " + driver.getMinorVersion() + " - " + driver.getMajorVersion());
    DriverManager.registerDriver(driver);
} else {
    getLogging().debug("Loading H2 driver.");
    Class.forName("org.h2.Driver");
}
outputDrivers();
this.con = DriverManager.getConnection(this.url, this.username, this.password);
break;

当我运行应用程序时出现此错误:

"*没有为 jdbc:h2:plugins\Odin\data\OdinStorage 找到合适的驱动程序;AUTO_RECONNECT=TRUE*"

这是完整的日志:

[Debug] Loading custom class loader for H2 driver: java.net.URLClassLoader@3bf3d5f4
[Debug] Loaded H2 driver: org.h2.Driver@67257ce8 - 3 - 1
[Debug] Checking DriverManager drivers.
[Debug] Found driver #1: sun.jdbc.odbc.JdbcOdbcDriver
[Debug] Found driver #2: com.mysql.jdbc.Driver
[Debug] Found 2 drivers in DriverManager.
--------------------------- STACKTRACE ERROR ---------------------------
Class name: java.sql.DriverManager
Error message: No suitable driver found for jdbc:h2:plugins\Odin\data\OdinStorage;AUTO_RECONNECT=TRUE
Error cause: null
File name: null
Function name: getConnection
Error line: -1
--------------------------- STACKTRACE START ---------------------------
java.sql.DriverManager.getConnection(Unknown Source)
java.sql.DriverManager.getConnection(Unknown Source)
com.craftfire.commons.managers.DataManager.connect(DataManager.java:756)
com.craftfire.commons.managers.DataManager.executeQuery(DataManager.java:526)
com.craftfire.odin.managers.StorageManager.checkInventoryDatabase(StorageManager.java:65)
com.craftfire.odin.managers.StorageManager.checkDatabases(StorageManager.java:56)
com.craftfire.odin.managers.StorageManager.<init>(StorageManager.java:34)
com.craftfire.odin.managers.OdinManager.loadDatabases(OdinManager.java:206)
com.craftfire.odin.managers.OdinManager.init(OdinManager.java:75)
com.craftfire.odin.layer.bukkit.Odin.onEnable(Odin.java:63)
org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:217)
org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:374)
org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:381)
org.bukkit.craftbukkit.CraftServer.loadPlugin(CraftServer.java:266)
org.bukkit.craftbukkit.CraftServer.enablePlugins(CraftServer.java:248)
org.bukkit.craftbukkit.CraftServer.<init>(CraftServer.java:200)
net.minecraft.server.ServerConfigurationManagerAbstract.<init>(ServerConfigurationManagerAbstract.java:50)
net.minecraft.server.ServerConfigurationManager.<init>(SourceFile:11)
net.minecraft.server.DedicatedServer.init(DedicatedServer.java:105)
net.minecraft.server.MinecraftServer.run(MinecraftServer.java:377)
net.minecraft.server.ThreadServerApplication.run(SourceFile:539)
---------------------------- STACKTRACE END ----------------------------

那么我的问题是,为什么驱动程序没有出现在 DriverManager.getDrivers() 中?

注意:我不希望将库添加到 CLASSPATH,这就是为什么我需要找到解决上述问题的方法。

我该如何解决这个问题?我只需要从 jar 中加载 H2 JDB 驱动程序。

我也试过这个:

  • 不使用 DriverManager.registerDriver(Driver),而是使用 Class.forName("org.h2.Driver", true, getClassLoader()) 代替,我也尝试过使用 .newInstance(),都没有成功。

谁能给我一个解决方案?

谢谢!

【问题讨论】:

  • 你的类路径中有 H2 的 JAR 文件吗?
  • 我不希望将驱动程序添加到我的类路径中,这就是为什么我要下载 jar 然后尝试加载它,这就是我需要解决方案的原因。
  • 为什么不想将它添加到类路径中?
  • 您必须将 JAR 文件添加到类路径中。这并不一定意味着更改全局 CLASSPATH 环境变量。还有其他几种方法可以做到这一点。

标签: java jdbc classloader h2


【解决方案1】:

我在我的 Kotlin 项目中遇到了同样的问题。 我已经在 bild.gradle.kts 中添加了

dependencies {
    implementation("com.h2database:h2:1.4.199")
..
}

然后在 IntelliJ File->Invalidate Cache 中。

【讨论】:

    【解决方案2】:

    在我的情况下,错误在 maven 范围内

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
            <scope>test</scope>
        </dependency>
    

    一旦您将其移除或将其更改为可见的范围,它就可以工作了

    【讨论】:

      【解决方案3】:

      您必须将确切 org.h2.Driver *.jar 文件名添加到应用程序的类路径中。

      示例/home/applications/games/minecraft/drivers/jdbcH2driver.jar

      因此,请确定驱动程序将始终在您的应用程序中的位置,并在安装使用它的应用程序时找到应用程序主文件夹路径以完全构建它。

      此外,它可能无法运行,因为在从网络下载期间可能需要一些时间,之后必须将其复制到“应用程序的类路径的正确文件夹”中才能使用它并具有正确的 .jar 名称(如上段)。 要成功下载“查询和应用程序操作应该放在一个线程中”以防止溢出到下一行指令。

      明智地,在应用程序启动时,您将检查 .jar 是否存在并下载它,如果它不存在并安装,同时向用户发出警告,如果 .jar 不存在则下载它。

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题。 h2 驱动程序在 pom.xml 中使用

        进行配置
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.193</version>
        </dependency>
        

        因为我在我的项目中使用 Java 6(不要问为什么 ;-))但是 Maven 存储库中的 h2-1.4.193.jar 依赖于 Java 7,所以无法使用此驱动程序版本。

        将 pom.xml 更改为使用 h2-1.4.190.jar 为我解决了这个问题。

        另见 h2database git 项目中的issue #300

        【讨论】:

          【解决方案5】:

          Hibernate 属性集 网址值: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

          驱动程序类名:

          <property name="driverClassName">
          <value>org.hibernate.dialect.H2Dialect</value>
          

          在 pom 中添加 H2 驱动:

              <dependency>
                  <groupId>com.h2database</groupId>
                  <artifactId>h2</artifactId>
                  <version>1.3.166</version>
              </dependency>
          

          【讨论】:

            【解决方案6】:

            对我来说,我在使用 groovygrapes 进行依赖解析时遇到了这个错误。

            解决办法:

            你需要告诉葡萄使用systemClassLoader。例如

            @GrabConfig(systemClassLoader=true)
            

            【讨论】:

              【解决方案7】:

              根据 Oracle 文档:http://docs.oracle.com/cd/E19501-01/819-3659/beadf/index.html

              类加载器将类加载委托给子类加载器,在类路径中搜索类。但是,您用于加载库的 URLClassloader 对系统或引导层次结构不可见,因此无法找到该类(尽管已加载,尽管在另一个 castl...classloader 中)。

              最简单的解决方案是将您的系统类加载器替换为 URLClassloader 并使用 addUrl(...path...) 加载您的库,正如这个答案所暗示的那样:How should I load Jars dynamically at runtime?

              【讨论】:

              • 附加说明:即使注册一个加载了“外星”类加载器的驱动程序也无济于事,因为驱动程序管理器会在请求驱动程序时检查这一点,例如创建连接时。请参阅 DriverManager 中的“isDriverAllowed(Driver driver, ClassLoader classLoader)”方法(我在 JDK7_u7 中检查过)。因此,您不能在不同的类加载器层次结构之间共享 JDBC 驱动程序。使用@Affess 提出的解决方案将解决这个问题。
              • 我个人认为这个答案是不正确的。我不同意有必要解决所有这些麻烦。将 JAR 放入您的 CLASSPATH 并继续使用它。
              • @duffymo - 在某些情况下,您可能不想将库隐藏到您的项目中,或者使用替代的 jdbc 连接器。仅仅因为没有看到用例并不意味着没有。
              • 但是您使用的是 H2 的 JDBC 连接器;你别无选择。你没有用这个解决方案解决任何问题。您只是通过使用与系统不同的类加载器来增加复杂性。除了“我说过”之外,您还没有描述任何用例。
              【解决方案8】:

              将 H2 JAR 添加到您的 CLASSPATH。

              没有合适的驱动程序通常意味着 URL 语法不正确。检查以确保您的符合要求。

              http://www.h2database.com/html/faq.html

              【讨论】:

              • 我不希望将 H2 jar 添加到我的类路径中,这就是我下载它的原因,但是加载下载的 jar 不起作用,这就是我试图找到的解决方案.
              • 您别无选择,我不明白您为什么不想将 H2 JAR 添加到您的 CLASSPATH 中。这就是 Java 的工作方式。
              猜你喜欢
              • 2015-07-12
              • 1970-01-01
              • 1970-01-01
              • 2020-05-02
              • 1970-01-01
              • 2019-05-25
              • 1970-01-01
              • 2012-12-09
              相关资源
              最近更新 更多