Skip to content
Java jdbc 7 min read

DriverManager

DriverManager is the original JDBC bootstrap class — the single entry point that turns a URL, username, and password into a live Connection to your database. It has been part of Java since JDBC 1.0 (Java 1.1) and remains the simplest way to open a database connection in standalone applications and tests.

What DriverManager Does

java.sql.DriverManager acts as a registry for JDBC drivers. When you call DriverManager.getConnection(url, user, pass), it:

  1. Iterates through every registered Driver implementation.
  2. Asks each driver “do you understand this URL?”
  3. Returns a Connection from the first driver that says yes.

That’s it — a simple find-the-right-driver, open-a-socket routine wrapped in a static utility class.

Note: DriverManager is a class, not an interface, and all its useful methods are static. You never instantiate it.

Getting a Connection

The most common overload takes a URL, username, and password:

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

public class DriverManagerDemo {
    public static void main(String[] args) throws SQLException {
        String url  = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC";
        String user = "root";
        String pass = "secret";

        try (Connection conn = DriverManager.getConnection(url, user, pass)) {
            System.out.println("Connected to: " + conn.getCatalog());
        }
        // Connection is closed automatically
    }
}

Output:

Connected to: mydb

Tip: Always wrap getConnection() in a try-with-resources block. Connection implements AutoCloseable, so the connection closes automatically when the block exits — even if an exception is thrown.

Three Overloads of getConnection

DriverManager offers three signatures to suit different configuration styles:

// 1. URL, username, password (most common)
Connection conn = DriverManager.getConnection(url, user, pass);

// 2. URL with credentials embedded in a Properties object
java.util.Properties props = new java.util.Properties();
props.setProperty("user", "root");
props.setProperty("password", "secret");
props.setProperty("useSSL", "false");
Connection conn2 = DriverManager.getConnection(url, props);

// 3. URL only — credentials embedded directly in the URL
// (avoid this; the password is visible in logs and stack traces)
Connection conn3 = DriverManager.getConnection(
    "jdbc:mysql://root:secret@localhost:3306/mydb");

The Properties overload is handy when you load config from a file at startup — just populate the Properties object from your config source and pass it in.

Warning: Never embed passwords in the URL (overload 3). URLs end up in log files, thread dumps, and error messages. Use the Properties overload or environment variables instead.

JDBC URL Format

Every driver recognises a URL with the form:

jdbc:<subprotocol>://<host>:<port>/<database>[?key=value&key=value]

Common examples:

DatabaseJDBC URL example
MySQLjdbc:mysql://localhost:3306/mydb
PostgreSQLjdbc:postgresql://localhost:5432/mydb
Oraclejdbc:oracle:thin:@localhost:1521:orcl
SQLitejdbc:sqlite:/path/to/file.db
H2 (mem)jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
SQL Serverjdbc:sqlserver://localhost:1433;databaseName=mydb

The subprotocol (mysql, postgresql, etc.) tells DriverManager which registered driver to use.

Driver Registration

Before DriverManager can hand out a connection, the driver must be registered with it. There are two ways this happens.

Automatic Registration (JDBC 4.0+, Java 6+)

Since JDBC 4.0, every properly built driver JAR includes a file at:

META-INF/services/java.sql.Driver

This file contains the fully qualified driver class name. When the JVM starts and the driver JAR is on the classpath, ServiceLoader reads this file and registers the driver automatically — you write zero registration code.

// Modern code — no Class.forName() needed
try (Connection conn = DriverManager.getConnection(url, user, pass)) {
    // works because the driver registered itself
}

Manual Registration (Legacy / JDBC < 4.0)

Before JDBC 4.0, you had to trigger class loading yourself:

// Old style — only needed before Java 6 / JDBC 4.0
Class.forName("com.mysql.cj.jdbc.Driver");

Loading the class caused the driver’s static initialiser to call DriverManager.registerDriver(new Driver()), adding itself to the internal list. You may still see this in older tutorials or codebases — it does no harm in modern Java but is completely unnecessary.

Note: You might also encounter DriverManager.registerDriver(driver) and DriverManager.deregisterDriver(driver) called explicitly in framework or test code that needs fine-grained control over which drivers are active.

Logging and Diagnostics

DriverManager has a built-in logging facility that predates java.util.logging. You can direct its output to any PrintWriter:

import java.io.PrintWriter;
import java.sql.DriverManager;

// Redirect DriverManager log output to stdout
DriverManager.setLogWriter(new PrintWriter(System.out, true));

// Now every getConnection() call will log driver-matching details
Connection conn = DriverManager.getConnection(url, user, pass);

Output (example):

DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb")
  trying com.mysql.cj.jdbc.Driver
  getConnection returning com.mysql.cj.jdbc.Driver

This is useful when debugging “No suitable driver found” errors — you can see exactly which drivers were tried.

Connection Timeout

You can set a global timeout (in seconds) that applies to every subsequent getConnection() call:

// Time out after 10 seconds if a connection cannot be established
DriverManager.setLoginTimeout(10);

try (Connection conn = DriverManager.getConnection(url, user, pass)) {
    System.out.println("Got a connection.");
} catch (SQLException e) {
    System.out.println("Could not connect: " + e.getMessage());
}

Note: Not all drivers honour setLoginTimeout. Check your driver documentation. For reliable timeout handling, use a connection pool like HikariCP, which provides driver-independent timeout configuration.

DriverManager vs DataSource

DriverManager is straightforward but is not the right tool for production applications. Use this table to decide:

FeatureDriverManagerDataSource (+ pool)
Connection poolingNo — new socket per callYes — reuses sockets
Typical connection latency50–200 ms< 1 ms (from pool)
Configuration (JNDI, env)ManualBuilt-in
Suitable for productionNoYes
Suitable for tests / scriptsYesOften overkill

In a production application, always use a DataSource backed by a connection pool — HikariCP is the industry standard for standalone Spring/Quarkus apps, while application servers (Tomcat, WildFly, GlassFish) provide their own pooled DataSource via JNDI.

Here is a minimal HikariCP setup that replaces DriverManager:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("secret");
config.setMaximumPoolSize(10);

HikariDataSource ds = new HikariDataSource(config);

try (Connection conn = ds.getConnection()) {  // drawn from the pool
    // use conn exactly as before
}

Your SQL code is identical — you just call ds.getConnection() instead of DriverManager.getConnection(). The pool manages the underlying sockets transparently.

Under the Hood

The Driver Registry

DriverManager keeps an internal CopyOnWriteArrayList<DriverInfo> (a thread-safe list). Each entry wraps a registered Driver instance alongside the ClassLoader that loaded it. When you call getConnection(), DriverManager iterates this list and calls driver.connect(url, props) on each driver. The first non-null Connection returned wins.

Class-Loader Awareness

DriverManager performs a security check: it only lets a driver serve a connection request if the driver was loaded by the same ClassLoader as the caller, or by an ancestor of it. This prevents one web application from stealing connections registered by another application in the same container. In module-aware environments (Java 9+, JPMS), ServiceLoader is invoked with the caller module’s context, providing similar isolation.

Why Each Open Connection is Expensive

When DriverManager.getConnection() returns, the JVM has:

  1. Performed a TCP three-way handshake with the database server.
  2. Exchanged authentication packets (TLS handshake if SSL is on, then credential exchange).
  3. Negotiated server capabilities (character set, time zone, protocol version).

All of that takes 50–200 ms on a local network — and much more over the internet. This is exactly why connection pools exist: they pay that cost once at startup and hand the already-authenticated socket to your code in microseconds.

Thread Safety

DriverManager.getConnection() is thread-safe — multiple threads can call it concurrently. The internal driver list is a CopyOnWriteArrayList, so reads (which dominate) are lock-free. Registration and deregistration are relatively rare and can afford the copy overhead.

Common Errors and Fixes

ErrorCauseFix
No suitable driver found for jdbc:...Driver JAR missing from classpathAdd the driver dependency (Maven/Gradle)
Communications link failureWrong host/port or DB not runningCheck URL; verify database server is up
Access denied for user '...'@'...'Wrong credentialsDouble-check username and password
Unknown database 'mydb'Database schema not createdRun CREATE DATABASE mydb; first
Connection hangs indefinitelyNo login timeout set, network issueCall DriverManager.setLoginTimeout(n) or use a pool
  • JDBC Drivers — Understand the four driver types and how ServiceLoader auto-discovers them at startup.
  • Steps to Connect a Database — A step-by-step walkthrough of every stage from loading the driver to closing resources.
  • Connection Interface — Everything a Connection object can do once DriverManager hands one to you.
  • PreparedStatement — The right way to run parameterised SQL once you have a connection — safer and faster than plain Statement.
  • Transaction Management — Control commit, rollback, and isolation levels on the Connection you received from DriverManager.
  • Connecting to MySQL — A concrete end-to-end example using DriverManager against a real MySQL database.
Last updated June 13, 2026
Was this helpful?