Skip to content

NativeLibraryManager.createConnection silently returns null on invalid URL instead of throwing SQLException #1374

@phyalexander

Description

@phyalexander

Describe the bug
The static method org.sqlite.JDBC.createConnection(String url, Properties prop) now silently returns null when the URL protocol is not handled by the driver (e.g., not starting with jdbc:sqlite:), instead of throwing SQLException with the message "invalid database address" as it did before.

This change was introduced in commit 392b7e7 ("return null if unhandled url protocol").

While returning null from Driver.connect() is correct JDBC behavior (to allow DriverManager to try other drivers), applying the same logic to the static convenience method JDBC.createConnection() is a breaking change. Code that calls this method directly expects either a valid Connection or an exception — not a silent null.

As a result, libraries and applications that use JDBC.createConnection (common with SQLite to avoid DriverManager overhead) now get NullPointerExceptions deep in their connection-handling code.

To Reproduce

Minimal pure-Java example (only sqlite-jdbc dependency required):

import org.sqlite.JDBC;
import java.sql.Connection;
import java.util.Properties;

public class Repro {
    public static void main(String[] args) throws Exception {
        String url = "jdbc:wrongprotocol:test.db";  // Invalid protocol
        Properties prop = new Properties();
        Connection conn = JDBC.createConnection(url, prop);
        // conn == null
        conn.close();  // → NullPointerException
    }
}

Real-world example from the ScalaSql library (https://github.com/com-lihaoyi/scalasql):

private def withConnection[T](f: DbClient.Connection => T): T = {
  val connection = dataSource.getConnection
  try f(new DbClient.Connection(connection, config, listeners))
  finally connection.close()  // ← NPE if connection is null
}

If the internal DataSource uses JDBC.createConnection (common pattern for SQLite), an invalid URL now causes NPE instead of early SQLException.

Expected behavior

  • The static JDBC.createConnection should continue to throw SQLException on invalid URLs (original behavior), as it is a convenience method intended for direct use with SQLite URLs.
  • Alternatively, if returning null is kept, it must be explicitly documented in Javadoc, and a warning should be logged. Existing callers should not break silently.

The method's contract (throws SQLException) suggests errors are reported via exceptions, not null returns.

Logs
Typical stack trace:

Caused by: java.lang.NullPointerException: Cannot invoke "java.sql.Connection.close()" because "connection" is null
    at scalasql.core.DbClient$DataSource.withConnection(DbClient.scala:136)
    ...

Environment

  • OS: Any
  • CPU architecture: Any
  • sqlite-jdbc version: All versions after commit 392b7e7 (including latest 3.51.1.0)

Additional context
The change improves compatibility when using DriverManager.getConnection with multiple drivers registered, but it breaks direct callers of JDBC.createConnection. Popular Scala libraries like ScalaSql (com-lihaoyi/scalasql) are affected because they follow the common pattern of calling the driver's static create method internally.

No documentation or changelog entry mentions this behavioral change or the new possibility of null return.

Suggested fixes:

  1. Restore throwing SQLException in JDBC.createConnection (preferred, non-breaking for existing code).
  2. Or add clear Javadoc + deprecation note + recommend switching to DriverManager.

Thanks for maintaining the driver!

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions