'Can't find class of postgresql driver

I'm trying to use HikariCP library for PostgreSQL connection pools in Java. I am using Maven, and I'm getting this error: java.lang.ClassNotFoundException: org.postgresql.Driver.

I have tried using different versions of the PostgreSQL driver, but none have worked to my advantage. (I have done more, but I've been faced with this problem, that I have not taken note of)

org.postgresql.ds.PGSimpleDataSource, org.postgresql.Driver and com.impossibl.postgres.jdbc.PGDataSource still produce this error, even though it is said in the HikariCP guide to use either the first or third. The second I found from research.

My maven:

(...)
    <build>
        <defaultGoal>clean package</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <minimizeJar>true</minimizeJar>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

    <repositories>
        <repository>
            <id>spigotmc-repo</id>
            <url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.spigotmc</groupId>
            <artifactId>spigot-api</artifactId>
            <version>1.12.2-R0.1-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.3.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.4</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.5</version>
        </dependency>
    </dependencies>
</project>

What I'm using to produce this error:

        try {
            Class.forName("org.postgresql.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("Failed to load.");
        }

        HikariConfig config = new HikariConfig("database.properties");
        ds = new HikariDataSource(config);

(The constructor HikariDataSource(config); produces this error aswell)

I believe the reason why this is happening is that the driver is not being made into the classpath - however, all efforts I have tried can't seem to do this. This problem of the driver not being in the final jar (to my belief): org.postgresql is not found in final jar.

Actual error:

[20:16:35 WARN]: java.lang.ClassNotFoundException: org.postgresql.Driver
[20:16:35 WARN]:        at java.net.URLClassLoader.findClass(Unknown Source)
[20:16:35 WARN]:        at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:152)
[20:16:35 WARN]:        at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:100)
[20:16:35 WARN]:        at java.lang.ClassLoader.loadClass(Unknown Source)
[20:16:35 WARN]:        at java.lang.ClassLoader.loadClass(Unknown Source)
[20:16:35 WARN]:        at java.lang.Class.forName0(Native Method)
[20:16:35 WARN]:        at java.lang.Class.forName(Unknown Source)
[20:16:35 WARN]:        at me.test.kitpvp.Kitpvp.onEnable(Kitpvp.java:43)
[20:16:35 WARN]:        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264)
[20:16:35 WARN]:        at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:337)
(...)
[20:16:35 INFO]: Failed to load.
[20:16:35 WARN]: 74 [Server thread] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...

Edits

  • Adding <scope>compile</scope> produced same results - did not work.


Solution 1:[1]

You can specify a filter to include the driver artifact in the shaded JAR:

<configuration>
   <minimizeJar>true</minimizeJar>
   <filters>
       <filter>
           <artifact>org.postgresql:postgresql</artifact>
           <includes>
               <include>**</include>
           </includes>
       </filter>
   </filters>

For more details: Selecting Contents for Uber JAR.

The issue occurs due to the (unfiltered) <minimizeJar>true</minimizeJar> configuration in your POM, and the fact that the driver class is not used at compile time.

maven-shade-plugin on minimizeJar:

When true, dependencies will be stripped down on the class level to only the transitive hull required for the artifact.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 sudeep