t8y2/dbx · error · IOException

Bundled H2 driver is missing: " + version.resourcePath()

Error message

Bundled H2 driver is missing: " + version.resourcePath()

What it means

extract() materializes a bundled H2 JAR from the classpath resource given by H2DriverVersion.resourcePath() into a cache directory. If getResourceAsStream returns null the bundled artifact was not packaged into the application, so an IOException is thrown rather than proceeding with a null stream.

Source

Thrown at agents/drivers/h2/src/main/java/com/dbx/agent/h2/H2DriverLoader.java:77

            H2DriverLoader.class.getClassLoader()
        );
        try {
            Driver driver = (Driver) Class.forName(effectiveDriverClass, true, classLoader).getDeclaredConstructor().newInstance();
            return new LoadedDriver(H2DriverVersion.CUSTOM, effectiveDriverClass + "|" + String.join("|", identities), driver, classLoader);
        } catch (Exception error) {
            closeAfterFailure(classLoader, error);
            throw error;
        } catch (LinkageError error) {
            closeAfterFailure(classLoader, error);
            throw error;
        }
    }

    private static Path extract(H2DriverVersion version) throws Exception {
        byte[] bytes;
        try (InputStream input = H2DriverLoader.class.getResourceAsStream(version.resourcePath())) {
            if (input == null) {
                throw new IOException("Bundled H2 driver is missing: " + version.resourcePath());
            }
            bytes = input.readAllBytes();
        }
        String digest = sha256(bytes);
        Path directory = CACHE_ROOT.resolve(version.version() + "-" + digest.substring(0, 16));
        Path target = directory.resolve("h2.jar");
        synchronized (EXTRACTION_LOCK) {
            Files.createDirectories(directory);
            if (!Files.isRegularFile(target) || Files.size(target) != bytes.length || !digest.equals(sha256(target))) {
                Path temporary = directory.resolve("h2.jar.tmp-" + UUID.randomUUID());
                Files.write(temporary, bytes);
                try {
                    Files.move(temporary, target, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
                } catch (java.nio.file.AtomicMoveNotSupportedException ignored) {
                    Files.move(temporary, target, StandardCopyOption.REPLACE_EXISTING);
                }
            }
        }

View on GitHub (pinned to c0390bff16)

Solutions

  1. Rebuild/repackage the driver module so the embedded H2 JAR resource is included (check shading excludes/resource filtering)
  2. Verify the resource exists on the classpath at version.resourcePath() (e.g. via Class.getResource)
  3. Configure a custom driver profile (h2-custom) with an external JAR path to bypass the bundled resource

Example fix

// before (maven-shade)
<exclude>com/dbx/agent/h2/drivers/*</exclude>
// after
<!-- remove the exclude so bundled h2 jars ship in the artifact -->
Defensive patterns

Strategy: try-catch

Validate before calling

boolean bundled = H2DriverLoader.class.getResource(version.resourcePath()) != null;

Try / catch

try {
    Path jar = H2DriverLoader.jar(version);
} catch (IOException e) {
    // fall back to h2-custom external JAR path
    return H2DriverLoader.loadExternal(externalJars, driverClass);
}

Prevention

When it happens

Trigger: Calling H2DriverLoader.jar() for a version (V1/V2/V3) whose embedded driver resource is absent from the classpath — e.g. the resource was excluded from the build or the loader JAR was repackaged without it.

Common situations: Fat-jar/shade build dropped resources under com/dbx/agent/h2/; resource filtered out by Maven/Gradle excludes; running from an IDE with incomplete classpath; custom build stripped embedded binaries.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/4ee69988c02fb3e6. Report an issue: GitHub.