baomidou/mybatis-plus · critical · IllegalStateException
There is neither 'privateLookupIn(Class, Lookup)' nor 'Looku
Error message
There is neither 'privateLookupIn(Class, Lookup)' nor 'Lookup(Class, int)' method in java.lang.invoke.MethodHandles.
What it means
In a static initializer, MybatisMapperProxy tries to obtain a method handle factory: first MethodHandles.privateLookupIn (JDK 9+), and on absence falls back to the JDK 8-era MethodHandles.Lookup(Class, int) constructor. If neither is retrievable, the class cannot initialize and throws IllegalStateException. This is a JVM-compatibility failure, not an application logic error.
Source
Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java:77
}
static {
Method privateLookupIn;
try {
privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
} catch (NoSuchMethodException e) {
privateLookupIn = null;
}
privateLookupInMethod = privateLookupIn;
Constructor<MethodHandles.Lookup> lookup = null;
if (privateLookupInMethod == null) {
// JDK 1.8
try {
lookup = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
lookup.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"There is neither 'privateLookupIn(Class, Lookup)' nor 'Lookup(Class, int)' method in java.lang.invoke.MethodHandles.",
e);
} catch (Exception e) {
lookup = null;
}
}
lookupConstructor = lookup;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);View on GitHub (pinned to bf67d90747)
Solutions
- Run on a standard JDK 8+ distribution (JDK 11/17 recommended) where privateLookupIn exists
- For GraalVM/native-image, register MethodHandles.Lookup for reflection in reflect-config / RuntimeReflection
- Upgrade mybatis-plus to a version matching your JVM; newer releases handle modern JDK encapsulation
- For Android, use a JVM-compatible runtime or a mybatis alternative designed for Android
Example fix
# before: runtime lacks Lookup(Class,int) and privateLookupIn java --add-opens java.base/java.lang=ALL-UNNAMED -jar app.jar # still fails if ctor filtered # after: use standard JDK 17 where privateLookupIn is present java -jar app.jar # requires JDK 9+
Defensive patterns
Strategy: fallback
Validate before calling
// At startup, verify the JVM can satisfy mapper proxy method-handle setup
try {
MethodHandles.Lookup lookup = (MethodHandles.Lookup) MethodHandles.class
.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class)
.invoke(null, MybatisMapperProxy.class, MethodHandles.lookup());
} catch (NoSuchMethodException e) {
// verify JDK8 fallback constructor exists
MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
} Try / catch
catch ExceptionInInitializerError / IllegalStateException from first mapper use; report 'unsupported runtime' to ops — no in-process retry or fallback is possible after class-init failure.
Prevention
- Pin a standard JDK (8/11/17/21) in deployment images and CI
- For native image builds, register MethodHandles.Lookup for reflection
- Run a mapper smoke test in the actual target runtime as a deploy gate
When it happens
Trigger: Running on a non-standard or stripped JVM/runtime where both privateLookupIn is missing and the Lookup(Class,int) constructor is absent or inaccessible (some Android runtimes, restricted JVM forks, or module-lockdown setups removing the constructor via reflection filters).
Common situations: Deploying mybatis-plus on Android/GraalVM native images with incomplete reflection metadata; JDK builds with strong encapsulation filters (e.g. --illegal-access=deny era / later JDKs where the private constructor is filtered); ahead-of-time compilation stripping the constructor.
Related errors
- %s already contains value for %s
- %s does not contain value for %s
- %s is ambiguous in %s (try using the full name including the
- Should be specified either value() or name() attribute in th
- Cannot use both value() and name() attribute in the @CacheNa
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/f562484395637fe2.
Report an issue: GitHub.