quarkusio/quarkus · error · IllegalStateException

Unable to instantiate the class:

Error message

Unable to instantiate the class: 

What it means

SchedulerUtils needs an instance of the @Scheduled business class. It first tries CDI bean lookup; if no bean matches (unsatisfied), it falls back to calling the public no-arg constructor via reflection. This IllegalStateException wraps any failure of that reflective instantiation (missing no-arg constructor, constructor throwing, non-public constructor, abstract class).

Source

Thrown at extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtils.java:124

    public static boolean isConfigValue(String val) {
        return isSimpleConfigValue(val) || isConfigExpression(val);
    }

    public static ZoneId parseCronTimeZone(Scheduled scheduled) {
        String timeZone = lookUpPropertyValue(scheduled.timeZone());
        return timeZone.equals(Scheduled.DEFAULT_TIMEZONE) ? null : ZoneId.of(timeZone);
    }

    public static <T> T instantiateBeanOrClass(Class<T> type) {
        Instance<T> instance = Arc.container().select(type, Any.Literal.INSTANCE);
        if (instance.isAmbiguous()) {
            throw new IllegalArgumentException("Multiple beans match the type: " + type);
        } else if (instance.isUnsatisfied()) {
            try {
                return type.getConstructor().newInstance();
            } catch (Exception e) {
                throw new IllegalStateException("Unable to instantiate the class: " + type);
            }
        } else {
            return instance.get();
        }
    }

    private static boolean isSimpleConfigValue(String val) {
        val = val.trim();
        return val.startsWith("{") && val.endsWith("}");
    }

    /**
     * Converts "{property}" to "${property}" for backwards compatibility
     */
    private static String adjustExpressionSyntax(String val) {
        if (isSimpleConfigValue(val)) {
            return '$' + val;
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add a CDI scope annotation (e.g. @ApplicationScoped or @Singleton) to the @Scheduled class so it is discovered as a bean
  2. Ensure the class has a public no-argument constructor if it is intentionally not a bean
  3. Make sure the constructor does not throw during instantiation
  4. Avoid annotating abstract classes with instance-level @Scheduled methods

Example fix

// before
class Tasks {
    Tasks(Service svc) { ... } // no no-arg ctor, not a bean
    @Scheduled(every = "10s") void run() {}
}
// after
@ApplicationScoped
class Tasks {
    @Inject Service svc;
    @Scheduled(every = "10s") void run() {}
}
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Tasks.class;
boolean ok = c.isAnnotationPresent(jakarta.inject.Scope.class)
    || java.lang.reflect.Modifier.isAbstract(c.getModifiers()) == false
        && java.util.Arrays.stream(c.getConstructors())
            .anyMatch(ctor -> ctor.getParameterCount() == 0);

Type guard

static boolean isInstantiable(Class<?> c) {
    return !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers())
        && java.util.Arrays.stream(c.getConstructors())
            .anyMatch(ctor -> java.lang.reflect.Modifier.isPublic(ctor.getModifiers())
                && ctor.getParameterCount() == 0);
}

Try / catch

try { new Tasks(); } catch (IllegalStateException e) {
    // fall back: register as CDI bean or fix no-arg constructor
}

Prevention

When it happens

Trigger: A class annotated with @Scheduled is not registered as a CDI bean (missing scope annotation) AND has no usable public no-argument constructor, or its constructor throws.

Common situations: Developer adds @Scheduled to a plain class without @ApplicationScoped/@Singleton; class has only constructor with parameters; constructor performs DI or IO that fails at build/startup; class is abstract or an inner non-static class.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/4ac8f69439877101. Report an issue: GitHub.