testcontainers/testcontainers-java · error · SQLException

Error while executing init function

Error message

Error while executing init function: {}::{}

What it means

runInitFunctionIfRequired invokes a static method (configured via TC_INITFUNCTION=class::method) with the connection and wraps ClassNotFoundException, NoSuchMethodException, IllegalAccessException and InvocationTargetException in this SQLException. The init function class or method could not be loaded/accessed, or the method itself threw.

Solutions

  1. Ensure the class is public, on the classpath, and the method is public static void name(java.sql.Connection)
  2. Verify the TC_INITFUNCTION format exactly: fully.qualified.Class::methodName
  3. Inspect getCause() (especially InvocationTargetException) for the real failure inside the method
  4. Simplify the init function to isolate the throwing code

Example fix

// before
public class Init { public static void setup() { ... } }
// after
public class Init { public static void setup(java.sql.Connection connection) { ... } }
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName("com.example.Init");
java.lang.reflect.Method m = c.getMethod("setup", java.sql.Connection.class);
int mods = m.getModifiers();
if (!java.lang.reflect.Modifier.isStatic(mods) || !java.lang.reflect.Modifier.isPublic(mods))
    throw new IllegalStateException("TC_INITFUNCTION must be public static void setup(Connection)");

Try / catch

try {
    runTestWithContainer();
} catch (SQLException e) {
    Throwable cause = e.getCause();
    if (cause instanceof java.lang.reflect.InvocationTargetException && cause.getCause() != null) {
        throw new RuntimeException("Init function failed", cause.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: jdbc:tc URL with TC_INITFUNCTION=com.example.Init::setup where the class is not on the test classpath, the method is not public static taking a Connection, or the invoked method throws an exception.

Common situations: Method signature wrong (must accept java.sql.Connection); class not visible to the driver's classloader; nested exception inside the init method; typo in class or method name.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/c021491b1e02a1b4. Report an issue: GitHub.

Appendix: source

Thrown at modules/jdbc/src/main/java/org/testcontainers/jdbc/ContainerDatabaseDriver.java:258

     * @param connection    JDBC connection to apply init functions to.
     * @throws SQLException on script or DB error
     */
    private void runInitFunctionIfRequired(final ConnectionUrl connectionUrl, Connection connection)
        throws SQLException {
        if (connectionUrl.getInitFunction().isPresent()) {
            String className = connectionUrl.getInitFunction().get().getClassName();
            String methodName = connectionUrl.getInitFunction().get().getMethodName();

            try {
                Class<?> initFunctionClazz = Class.forName(className);
                Method method = initFunctionClazz.getMethod(methodName, Connection.class);

                method.invoke(null, connection);
            } catch (
                ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e
            ) {
                LOGGER.error("Error while executing init function: {}::{}", className, methodName, e);
                throw new SQLException("Error while executing init function: " + className + "::" + methodName, e);
            }
        }
    }

    @Override
    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
        return delegate != null ? delegate.getPropertyInfo(url, info) : new DriverPropertyInfo[0];
    }

    @Override
    public int getMajorVersion() {
        return delegate != null ? delegate.getMajorVersion() : 1;
    }

    @Override
    public int getMinorVersion() {
        return delegate != null ? delegate.getMinorVersion() : 0;
    }

View on GitHub (pinned to 8e549514e3)