Java Sql Driver Class Not Found Jar With Command Line Run

Viewed 199

I've been trying to run my Maven Kotlin Ktor project with command line. The project contains the MySQL configuration too. Every time I tried to hit the following command, I got the following error.

Here is my command.

kotlin -cp mysql-connector-java-8.0.30.jar:dev_meet_dev_api.jar MainClassKt

The dev_meet_dev_api.jar file is my project jar and mysql-connector-java-8.0.30 is for MySQL connection with the database. My project is dependent on MySQL connector that's why I added the external dependency for MySQL connector.

As soon I hit the above command on terminal I've got the following error.

Caused by: java.lang.ClassNotFoundException: java.sql.Driver
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)

Edit 1: Added the maven file.

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>spartons.com.devMeetdevApi</groupId>
    <artifactId>KtorTesting</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <kotlin.version>1.7.10</kotlin.version>
        <ktor.version>2.1.1</ktor.version>
        <junit.version>4.12</junit.version>
        <serialization.version>1.4.0</serialization.version>
        <coroutines.version>1.6.4</coroutines.version>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
        <kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget>
        <kotlin.code.style>official</kotlin.code.style>
        <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
    </properties>

    <dependencies>

        <!--   Kotlin language dependencies   -->

        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
            <version>${kotlin.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!--   Kotlin's coroutines dependency   -->

        <dependency>
            <groupId>org.jetbrains.kotlinx</groupId>
            <artifactId>kotlinx-coroutines-core</artifactId>
            <version>${coroutines.version}</version>
        </dependency>

        <!--  Ktor dependencies   -->

        <dependency>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-core-jvm</artifactId>
            <version>${ktor.version}</version>
        </dependency>
        <dependency>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-jetty-jvm</artifactId>
            <version>${ktor.version}</version>
        </dependency>
        <dependency>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-content-negotiation-jvm</artifactId>
            <version>${ktor.version}</version>
        </dependency>
        <dependency>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-serialization-kotlinx-json-jvm</artifactId>
            <version>${ktor.version}</version>
        </dependency>
        <dependency>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-status-pages-jvm</artifactId>
            <version>${ktor.version}</version>
        </dependency>
        <dependency>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-cors-jvm</artifactId>
            <version>${ktor.version}</version>
        </dependency>

        <!--  Kotlin serialization version   -->

        <dependency>
            <groupId>org.jetbrains.kotlinx</groupId>
            <artifactId>kotlinx-serialization-json</artifactId>
            <version>${serialization.version}</version>
        </dependency>

        <!--  MySQL connector dependency   -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <finalName>dev_meet_dev_api</finalName>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <compilerPlugins>
                        <plugin>kotlinx-serialization</plugin>
                    </compilerPlugins>
                    <args>
                        <arg>-opt-in=kotlin.RequiresOptIn</arg>
                    </args>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-serialization</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-compile</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>default-testCompile</id>
                        <phase>none</phase>
                    </execution>
                </executions>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <artifactSet>
                        <excludes>
                            <exclude>mysql:mysql-connector-java:jar:</exclude>
                        </excludes>
                    </artifactSet>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Edit 2: Added the java-11 modules enter image description here

P.S I'm using Java 11. Projects works fine if I try to run with the IntelliJ.

3 Answers

You can do this directly in Maven! In your pom.xml add the driver as a dependency.

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>

Then you shade the dependency into the jar

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                            <includes>
                                <include>mysql:mysql-connector-java</include>
                            </includes>
                        </artifactSet>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Then directly execute the jar. If this does not help may I know which Java version you are using?

Kotlin applications need the Kotlin runtime to run (mainly kotlin-stdlib.jar). It can be included in the application jar or not.

If the runtime is not included, you must add it to the classpath:

java -cp /path/to/kotlin-stdlib.jar:app.jar MainClassKt

You can also use the kotlin script, which automatically adds it:

kotlin -cp app.jar MainClassKt

In your case, the runtime is included thanks to the maven-shade-plugin, so you can run the app like this:

java -cp mysql-connector-java-8.0.30.jar:dev_meet_dev_api.jar MainClassKt

Possibility 1

It is possible that some dependency that you manually added has a different version of java.sql.Driver. It is overriding the java.sql.Driver dependency version that your code flow needs.

To debug if this is actually the cause of your problem, you can use IntelliJ maven dependency plugin. It can show if there is any conflict in dependency causing the needed class to not load. https://www.jetbrains.com/help/idea/work-with-maven-dependencies.html#maven_dependency_diagram

Also, please note that in my experience, If multiple dependencies are loading different versions of same class, then you may get different results in different setup, since order of class loading may differ. This can result in your code working in IntellijIdea, but not when running from terminal.

Possibility 2

Check if the jdbc driver version is compatible with java and database versions that you are using. Try upgrading or downgrading the jdbc version to see if that resolves issue.

Debug approach 1: if above ways don't fix the issue

Since you say that your code works in Intellij, start your application in debug mode and put a debug point in java.sql.Driver. See which the library which contains this class and the dependency which contains this library. That can help you debug the cause of problem.

Debug approach 2: if above ways don't fix the issue

Use remote debugging. Start your jar application in console with remote debug enabled.

Refer this on steps to do it. https://www.jetbrains.com/help/idea/tutorial-remote-debug.html#ecd9fef1

Using this, you can find the code flow and the cause of problem for program that runs in console.

I hope that this helps you.

Related