最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Java: Error 'Could not find or load main class' when running compiled class with PostgreSQL JDBC driver - Stack

programmeradmin4浏览0评论

I'm trying to connect to a PostgreSQL database using Java and the postgresql-42.7.5.jar JDBC driver.

I have the following files in the project directory:

Main.java, Main.class, postgresql-42.7.5.jar

Main.java:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    private static final String URL = "jdbc:postgresql://localhost:5432/testdb";
    private static final String USER = "testuser";
    private static final String PASSWORD = "password";

    public static void main(String[] args) {
        try {
            Class.forName(".postgresql.Driver");
            Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
            System.out.println("Connected to PostgreSQL successfully!");
            connection.close();
        } catch (ClassNotFoundException e) {
            System.err.println("PostgreSQL Driver not found!");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("Connection failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

I successfully compile the code using:

javac -cp .:postgresql-42.7.5.jar Main.java

However, when I try to run it, I get the following error:

java -cp .:postgresql-42.7.5.jar Main


Error: Could not find or load main class Main
Caused by: java.lang.ClassNotFoundException: Main

I'm trying to connect to a PostgreSQL database using Java and the postgresql-42.7.5.jar JDBC driver.

I have the following files in the project directory:

Main.java, Main.class, postgresql-42.7.5.jar

Main.java:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    private static final String URL = "jdbc:postgresql://localhost:5432/testdb";
    private static final String USER = "testuser";
    private static final String PASSWORD = "password";

    public static void main(String[] args) {
        try {
            Class.forName(".postgresql.Driver");
            Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
            System.out.println("Connected to PostgreSQL successfully!");
            connection.close();
        } catch (ClassNotFoundException e) {
            System.err.println("PostgreSQL Driver not found!");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("Connection failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

I successfully compile the code using:

javac -cp .:postgresql-42.7.5.jar Main.java

However, when I try to run it, I get the following error:

java -cp .:postgresql-42.7.5.jar Main


Error: Could not find or load main class Main
Caused by: java.lang.ClassNotFoundException: Main
Share Improve this question edited Mar 21 at 23:10 Drax asked Mar 21 at 22:04 DraxDrax 1691 silver badge9 bronze badges 4
  • "I successfully compile the code using: java ... Main" -- usually we use javac and the file name with extension (Main.java) to compile; java is used to execute (btw, which OS?) – user85421 Commented Mar 21 at 22:09
  • Thank you for pointing that out. I fot to include "javac" and "Main.java" in the description. I am using Git Bash on Windows. – Drax Commented Mar 21 at 23:17
  • even using the bash, most probably you are using the java.exe executable - and Windows require ; as path separator in the class path (since : is used to specify the drive - e.g. D:\...) -- but ; is also interpreted by bash, so it needs to be escaped: java -cp .\;some.jar Main – user85421 Commented Mar 22 at 8:05
  • I've successfully established a connection to PostgreSQL. Thank you all for the help and detailed explanation. By quoting the classpath and using the semicolon as the classpath delimiter, success was achieved. The commands used were: javac -cp ".;postgresql-42.7.5.jar" Main.java java -cp ".;postgresql-42.7.5.jar" Main – Drax Commented Mar 22 at 10:53
Add a comment  | 

1 Answer 1

Reset to default 1

The path separator on windows is the ;, not the :.

Most developers are on a posix-like system, either because their OS is posix compatible (mac, linux), or they develop on windows but in a posixy environment (a bash shell, for example).

This popularity means tutorials and documentation is generally not written primarily with powershell or a windows terminal (cmd.exe) in mind. This can go so far that they just assume the reader is on a posixy system.

Not much you can do about it, except keep an eye out. Java development generally doesn't care much about your underlying OS (not just 'java', the entire ecosystem, e.g. all IDEs run on all major OSes and look about the same on all of them). Point is, here, it 'caught' you, because that's one difference that matters.

The reason is that on windows specifically : means something in paths (drive letter separator); on posix file systems it does not. Java started on posixy systems and used : because it was "available", then on windows that was a problem so specifically on windows ; is used.

It 'works' with your javac command because you aren't using the postgres driver in your compilation at all (you do not refer to it anywhere. Yes, you pass the name of it to Class.forName but that's just a string, the compiler just compiles 'make this string, write the bytecode that invokes Class.forName, whatever that might be, and that's all you have to d') - in other words, you can write javac -cp whateverInvalidCrudYouPlease Main.java and it'll work just fine because that command doesn't need a classpath for anything it's going to do.

At runtime however both . and the psql driver has to be there or it won't work. Hence, -cp actually matters, and thus, your incorrect cp param causes that error to occur.

The fix is to use ;:

java -cp .;postgresql-42.7.5.jar Main

NB: The Class.forName line does nothing; some tutorials include it but that means they are either written by newbies/clueless folks, or it's 20 years old, not a good start. Just remove the line. Or if you want an actual compilation failure if the classpath isn't set up right, make that .postgresql.Driver.class.getName(); to ensure it'll fail if your classpath isn't in order. I don't really recommend doing that; it's not idiomatic java.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论