apache/incubator-seata · error · IllegalStateException

Extension instance(definition: {}, class: {}) could not be

Error message

Extension instance(definition: {}, class: {})  could not be instantiated: {}

What it means

createNewExtension reflectively instantiates an SPI implementation (initInstance). If the constructor or initialization throws, it is wrapped in IllegalStateException naming the ExtensionDefinition and service type, with the original throwable as cause. This distinguishes 'provider found but cannot be constructed' from 'provider not found'.

Source

Thrown at common/src/main/java/org/apache/seata/common/loader/EnhancedServiceLoader.java:499

                        if (instance == null) {
                            instance = createNewExtension(definition, loader, argTypes, args);
                            holder.set(instance);
                        }
                    }
                }
                return (S) instance;
            } else {
                return createNewExtension(definition, loader, argTypes, args);
            }
        }

        private S createNewExtension(
                ExtensionDefinition<S> definition, ClassLoader loader, Class<?>[] argTypes, Object[] args) {
            Class<S> clazz = definition.getServiceClass();
            try {
                return initInstance(clazz, argTypes, args);
            } catch (Throwable t) {
                throw new IllegalStateException(
                        "Extension instance(definition: " + definition + ", class: " + type
                                + ")  could not be instantiated: " + t.getMessage(),
                        t);
            }
        }

        private List<Class<S>> loadAllExtensionClass(ClassLoader loader, boolean includeCompatible) {
            List<ExtensionDefinition<S>> definitions = definitionsHolder.get();
            if (definitions == null) {
                synchronized (definitionsHolder) {
                    definitions = definitionsHolder.get();
                    if (definitions == null) {
                        definitions = findAllExtensionDefinition(loader, includeCompatible);
                        definitionsHolder.set(definitions);
                    }
                }
            }
            return definitions.stream()

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Read the cause (t) — its message and class identify the actual construction failure.
  2. Give the provider a public constructor matching the argTypes passed to load(), typically a no-arg constructor.
  3. Move provider initialization work out of the constructor into an init/lifecycle method.
  4. Ensure the provider class is concrete and public.

Example fix

// before
public class MyRegistryProvider implements RegistryProvider {
  public MyRegistryProvider(String addr) { ... } // no no-arg ctor -> instantiation fails
}

// after
public class MyRegistryProvider implements RegistryProvider {
  public MyRegistryProvider() { this.addr = System.getProperty("registry.addr")); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Optional pre-check that the provider class has a usable constructor
Class<?> c = Class.forName(implName);
if (!Modifier.isPublic(c.getModifiers()) || Modifier.isAbstract(c.getModifiers())) {
    throw new IllegalArgumentException("SPI impl must be public and concrete: " + implName);
}
if (Stream.of(c.getConstructors()).noneMatch(ctor -> ctor.getParameterCount() == 0)) {
    throw new IllegalArgumentException("SPI impl needs a public no-arg constructor: " + implName);
}

Try / catch

try {
    T provider = EnhancedServiceLoader.load(SpiType.class);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("could not be instantiated")) {
        Throwable real = e.getCause(); // actual constructor/init failure
        log.error("Provider init failed: {}", real, real);
    }
    throw e;
}

Prevention

When it happens

Trigger: Any EnhancedServiceLoader.load call where the selected provider class exists but initInstance fails: constructor exception, incompatible constructor signature when args are passed, abstract class registered as provider, or static initializer failure.

Common situations: Custom seata extensions with constructors requiring arguments while the loader calls the no-arg/argTypes path; providers depending on configuration that is not yet initialized at load time; JDK/security restrictions blocking reflective access.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/d6e65e6bf760b829. Report an issue: GitHub.