4

Writing a pure Java server app for Heroku using Maven. Connecting to Heroku's Postgres database.
Everything works when running locally, using IntelliJ's config for running Java apps, specifying Heroku's DB URL as an environment variable. The app works, and I can connect to the DB.
Note: I found out that IntelliJ somehow automatically uses its own Postgres driver, the one that I specified in pom.xml gets ignored, obviously
However, when I deploy the app, i get the following error in my Heroku log as soon as I connect to the DB:
java.lang.ClassNotFoundException: org.postgresql.Driver

I followed the Heroku tutorial, but when I saw that there is no connection, I put

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

before

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

just to make sure the driver gets found. If I remove Class.forName()... check, I get the no suitable driver found for [my db url] error.
Concerning the last error, I tried both JDBC_DATABASE_URL and DATABASE_URL env vars, and even constructing the DB URL "by hand", with sslmode=require etc, but still no luck.
My pom.xml has modelVersion, groupId, artifactId, version and name specified, as well as:

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

My Procfile, that Heroku uses to launch the app, looks like this:

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

When I deploy the app, I get no errors, build is successful.

What can be the cause of the driver not loading? Am I forgetting something in pom.xml, or Procfile, or something else?

7
  • To clarify, when you add the Class.forName call, does the DB connection work? Commented Apr 17, 2016 at 22:44
  • locally, forName() catches the IntelliJ's jdbc driver and the connection works. On Heroku, forName() triggers the ClassNotFoundException Commented Apr 17, 2016 at 22:47
  • Can you check if the postgres jar file is in your Heroku slug by running heroku run ls target/dependency/? Commented Apr 17, 2016 at 22:48
  • I get ls: cannot access target/dependency/: No such file or directory Commented Apr 17, 2016 at 22:51
  • 1
    That would suggest your JAR files are not being vendored (i.e. copied into the target directory during the build). Are you deploying with git push or mvn heroku:deploy? Commented Apr 17, 2016 at 22:53

4 Answers 4

1

Sometimes, convenience (like using IntelliJ's git integration to push to Heroku like I did) leads to unwanted problems.

I used git push to update my app on Heroku. Everything was fine, except the required libraries didn't fall into place.
Tried mvn heroku:deploy, tested, everything works! Thanks codefinger for the suggestion.

If anyone asks, here's how you do it if never done before:
1) Add the Heroku Maven Plugin to your pom.xml:

    <build>
        <plugins>
            <plugin>
                <groupId>com.heroku.sdk</groupId>
                <artifactId>heroku-maven-plugin</artifactId>
                <version>2.0.6</version>
            </plugin>
        </plugins>
    </build>

2) Execute maven goal heroku:deploy.
That's it

Sign up to request clarification or add additional context in comments.

Comments

1

I had the same problem with connection working from local system, but not when deployed. Was the same issue, not having dependencies accessible, but for a build using a JAR, I just needed to make sure that I used a JAR that was self contained with all dependencies.

Comments

1

There is a more direct solution than switching to heroku-maven-plugin: you can mark the postgresql dependency as having runtime scope:

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

The default scope is compile, which results in Maven leaving it out since it's not referenced in the code.

I've added this answer because I ran into the same issue but had a lot of trouble with the heroku-maven-plugin approach (my project has multiple modules and that complicates things). Adopting the plugin probably has other benefits, but configuring the dependency's scope was a much simpler fix in my case.

Comments

0

Quoting Heroku Help:

This means you have parsed the DATABASE_URL wrong. You need to change postgres to postgresql in the connection string (JDBC does not support the "postgres" shorthand), or use the JDBC_DATABASE_URL config variable instead.

Also, make sure the dependency is runtime only.

source

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.