quarkusio/quarkus · error · ConfigurationException

Thread pool class not found: ${threadPoolClass}

Error message

Thread pool class not found: ${threadPoolClass}

What it means

Quarkus Quartz deployment validates the custom thread pool class configured via quarkus.quartz.thread-pool.class by loading it with Class.forName at build time. When the class cannot be found on the application classpath, a ConfigurationException with this message is thrown, failing the build. This guard exists so Quartz can instantiate the pool and register it for reflection (native image support).

Source

Thrown at extensions/quartz/deployment/src/main/java/io/quarkus/quartz/deployment/QuartzProcessor.java:249

            reflectiveClasses.add(ReflectiveClassBuildItem.builder(
                    String.class,
                    JobDataMap.class,
                    DirtyFlagMap.class,
                    StringKeyDirtyFlagMap.class,
                    HashMap.class)
                    .reason(getClass().getName())
                    .serialization(true).build());
        }

        Class<?> threadPoolClass;
        try {
            threadPoolClass = Class.forName(config.threadPoolClass(), false, Thread.currentThread().getContextClassLoader());
            if (!ThreadPool.class.isAssignableFrom(threadPoolClass)) {
                throw new ConfigurationException(
                        "Thread pool class does not implement ThreadPool interface spi: " + config.threadPoolClass());
            }
        } catch (ClassNotFoundException e) {
            throw new ConfigurationException("Thread pool class not found: " + config.threadPoolClass());
        }

        reflectiveClasses.add(ReflectiveClassBuildItem.builder(threadPoolClass, SimpleInstanceIdGenerator.class)
                .reason(getClass().getName())
                .methods().build());
        reflectiveClasses
                .add(ReflectiveClassBuildItem.builder(CascadingClassLoadHelper.class, InitThreadContextClassLoadHelper.class)
                        .reason(getClass().getName())
                        .build());
        reflectiveClasses.add(ReflectiveClassBuildItem.builder(config.storeType().clazz)
                .reason(getClass().getName())
                .methods().fields().build());

        if (config.storeType().isDbStore()) {
            reflectiveClasses.add(ReflectiveClassBuildItem.builder(
                    JobStoreSupport.class,
                    AbstractTrigger.class,
                    SimpleTriggerImpl.class,

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the fully-qualified class name in quarkus.quartz.thread-pool.class (check spelling and package).
  2. Add the artifact containing the ThreadPool implementation as a dependency of the application.
  3. Ensure the class implements org.quarkus... org.quartz.spi.ThreadPool (the next validation would reject it otherwise).
  4. If no custom pool is needed, remove the property to fall back to the default thread pool.

Example fix

// before (application.properties)
quarkus.quartz.thread-pool.class=com.myapp.CustomPool

// after (correct FQN + dependency present)
quarkus.quartz.thread-pool.class=com.myapp.quartz.CustomThreadPool
Defensive patterns

Strategy: validation

Validate before calling

// build-time check: ensure the class is loadable and implements ThreadPool
String fqn = "com.myapp.quartz.CustomThreadPool"; // value of quarkus.quartz.thread-pool.class
try {
    Class<?> c = Class.forName(fqn, false, Thread.currentThread().getContextClassLoader());
    if (!org.quartz.spi.ThreadPool.class.isAssignableFrom(c)) {
        throw new IllegalStateException(fqn + " must implement org.quartz.spi.ThreadPool");
    }
} catch (ClassNotFoundException e) {
    throw new IllegalStateException("thread-pool class not on classpath: " + fqn, e);
}

Prevention

When it happens

Trigger: Set quarkus.quartz.thread-pool.class to a class name that is not on the application's classpath at build time (typo, missing dependency, wrong package, class only available at runtime).

Common situations: Typo in the fully-qualified class name; custom ThreadPool implementation lives in a module not declared as a dependency; class was renamed/moved during a Quartz or app upgrade; using a library thread pool class excluded from the Quarkus app.

Related errors


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