mybatis/mybatis-3 · error · LogException

Error setting Log implementation. Cause: {}

Error message

Error setting Log implementation.  Cause: {}

What it means

LogFactory.setImplementation(Class) throws LogException when the candidate Log implementation cannot be adopted: it has no constructor accepting String, instantiating it fails, or invoking isDebugEnabled/debug throws. This runs for every use*Logging() call and during static initialization when LogFactory probes the classpath for the first available adapter.

Source

Thrown at src/main/java/org/apache/ibatis/logging/LogFactory.java:116

      try {
        runnable.run();
      } catch (Throwable t) {
        // ignore
      }
    }
  }

  private static void setImplementation(Class<? extends Log> implClass) {
    lock.lock();
    try {
      Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
      Log log = candidate.newInstance(LogFactory.class.getName());
      if (log.isDebugEnabled()) {
        log.debug("Logging initialized using '" + implClass + "' adapter.");
      }
      logConstructor = candidate;
    } catch (Throwable t) {
      throw new LogException("Error setting Log implementation.  Cause: " + t, t);
    } finally {
      lock.unlock();
    }
  }

}

View on GitHub (pinned to 008069adb1)

Solutions

  1. If using useCustomLogging, give the class a public constructor taking a single String and make sure it does not throw.
  2. Add the missing backend dependency (e.g. org.slf4j:slf4j-api) that matches the use*Logging() call.
  3. Check the chained cause to see whether it is a NoSuchMethodException (constructor) or a backend instantiation error (classpath).
  4. As a last resort for isolated tests, use LogFactory.useStdOutLogging().

Example fix

// before
public class MyLog implements Log {
  public MyLog() {} // no String constructor -> setImplementation fails
}
LogFactory.useCustomLogging(MyLog.class);

// after
public class MyLog implements Log {
  public MyLog(String name) {} // matches required signature
}
LogFactory.useCustomLogging(MyLog.class);
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the adapter class satisfies the contract before switching
void safeUse(Class<? extends Log> impl) {
  try {
    impl.getConstructor(String.class); // required signature
  } catch (NoSuchMethodException e) {
    throw new IllegalStateException(impl + " needs a public Log(String) constructor");
  }
  LogFactory.useCustomLogging(impl);
}

Try / catch

try {
  LogFactory.useSlf4jLogging();
} catch (LogException e) {
  throw new IllegalStateException("slf4j-api missing on classpath; add org.slf4j:slf4j-api", e);
}

Prevention

When it happens

Trigger: Calling useCustomLogging(MyLog.class) where MyLog lacks a public Log(String) constructor or throws in it; calling useSlf4jLogging()/useLog4J2Logging() etc. when the corresponding backend jar is absent (the probe's newInstance throws).

Common situations: Custom Log implementations with wrong constructor signature; SLF4J/Log4j2/Logging commons jar missing from dependencies so the explicit switch fails; static-init probing order changed across MyBatis versions producing a different first-pick failure.

Related errors


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/4c98a35ebd830fa9. Report an issue: GitHub.