Heroku无法找到Postgres JDBC驱动程序。

4
使用Maven为Heroku编写一个纯Java服务器应用程序。 连接到Heroku的Postgres数据库。
当使用IntelliJ的Java应用程序配置在本地运行时,将Heroku的DB URL作为环境变量指定,一切都正常运作。应用程序可以工作,并且我可以连接到DB。
注意:我发现IntelliJ不知何故自动使用自己的Postgres驱动程序,而我在pom.xml中指定的那个驱动被忽略了,显然。
然而,当我部署这个应用程序时,一旦连接到DB,我会在Heroku日志中得到以下错误:
java.lang.ClassNotFoundException: org.postgresql.Driver

我按照Heroku的教程操作,但当发现无法连接时,我进行了如下操作:

Class.forName("org.postgresql.Driver");

之前

String dbUrl = System.getenv("JDBC_DATABASE_URL");
return DriverManager.getConnection(dbUrl);

为了确保驱动程序被找到,我加入了Class.forName()...检查。如果删除此检查,会出现no suitable driver found for [我的数据库URL]错误。
关于最后一个错误,我尝试使用JDBC_DATABASE_URLDATABASE_URL环境变量,甚至手动构建DB URL,包括sslmode=require等,但仍然没有成功。
我的pom.xml文件中指定了modelVersion、groupId、artifactId、versionname,以及以下内容:

<dependencies>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.4.1208</version>
    </dependency>
</dependencies>

我在Heroku上启动应用时使用的Procfile文件如下:

web: java $JAVA_OPTS -cp target/classes:"target/dependency/*" Main --port $PORT

我部署应用程序时没有出现任何错误,构建成功。

驱动程序无法加载的原因是什么? 我在pom.xml或Procfile或其他某处忘记了什么吗?


请说明一下,当您添加 Class.forName 调用后,数据库连接是否有效? - codefinger
你能否通过运行 heroku run ls target/dependency/ 命令来检查 Postgres jar 文件是否在你的 Heroku slug 中? - codefinger
我得到了 ls: cannot access target/dependency/: No such file or directory - kit
1
这可能意味着您的JAR文件没有被打包(即在构建过程中未复制到目标目录)。您是使用git push还是mvn heroku:deploy进行部署? - codefinger
太好了!感谢 @codefinger 解决了持续几天的谜团! - kit
显示剩余2条评论
4个回答

1

我也遇到了从本地系统连接正常,但部署后无法连接的问题。原因是同样的,依赖项不可访问。但对于使用JAR构建的情况,我只需要确保使用一个自包含所有依赖项的JAR即可。


1
有时候,方便的操作(比如像我一样使用IntelliJ的git集成推送到Heroku)会导致不必要的问题。
我使用git push更新我的Heroku应用程序。一切都很好,但是所需的库没有放在正确的位置。
尝试了mvn heroku:deploy,测试了一下,一切都正常!感谢codefinger的建议。
如果有人问起,以下是第一次使用的步骤:
1)将Heroku Maven Plugin添加到您的pom.xml中:
    <build>
        <plugins>
            <plugin>
                <groupId>com.heroku.sdk</groupId>
                <artifactId>heroku-maven-plugin</artifactId>
                <version>2.0.6</version>
            </plugin>
        </plugins>
    </build>

2) 执行maven目标 heroku:deploy
就这样。


1

有一个比切换到heroku-maven-plugin更直接的解决方案:您可以将postgresql依赖项标记为具有runtime作用域:

<dependencies>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.3.1</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

默认作用域是compile,这会导致Maven在代码中没有引用它时将其排除。

我添加了这个答案,因为我遇到了同样的问题,但是使用heroku-maven-plugin方法时遇到了很多麻烦(我的项目有多个模块,这使得事情变得复杂)。采用插件可能还有其他好处,但在我的情况下,配置依赖项的作用域是一个更简单的解决方法。


0

引用 Heroku 帮助:

这意味着您已经错误解析了 DATABASE_URL。您需要在连接字符串中将 postgres 更改为 postgresql(JDBC 不支持“postgres”速记),或者改用 JDBC_DATABASE_URL 配置变量。

此外,请确保依赖项仅在运行时存在

源代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接