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
- If using useCustomLogging, give the class a public constructor taking a single String and make sure it does not throw.
- Add the missing backend dependency (e.g. org.slf4j:slf4j-api) that matches the use*Logging() call.
- Check the chained cause to see whether it is a NoSuchMethodException (constructor) or a backend instantiation error (classpath).
- 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
- Give custom Log implementations a public (String) constructor that never throws.
- Match each use*Logging() call with the corresponding backend dependency in the build file.
- Fail fast at startup rather than discovering logging problems during first SQL execution.
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
- Error setting driver on UnpooledDataSource.
- Cannot find class: {}
- Could not find resource {}
- Error creating logger for logger {}. Cause: {}
- Could not resolve type alias '{}'. Cause: {}
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/4c98a35ebd830fa9.
Report an issue: GitHub.