quarkusio/quarkus · error · java.lang.IllegalStateException

Unable to instantiate ParserHook: <engineConfigClass>

Error message

Unable to instantiate ParserHook: <engineConfigClass>

What it means

Analogous to the SectionHelperFactory case: analyzeTemplates reflectively instantiates each registered ParserHook implementation via its no-arg constructor. Failure to load or instantiate (missing constructor, throwing constructor, classloading issue) aborts the build with this IllegalStateException carrying the underlying cause.

Source

Thrown at extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java:702

            for (ClassInfo engineConfigClass : engineConfigurations.get().getConfigurations()) {
                if (Types.isImplementorOf(engineConfigClass, Names.SECTION_HELPER_FACTORY, index)) {
                    try {
                        Class<?> sectionHelperFactoryClass = tccl.loadClass(engineConfigClass.toString());
                        SectionHelperFactory<?> factory = (SectionHelperFactory<?>) sectionHelperFactoryClass
                                .getDeclaredConstructor().newInstance();
                        builder.addSectionHelper(factory);
                        LOGGER.debugf("SectionHelperFactory registered during template analysis: %s", engineConfigClass);
                    } catch (Exception e) {
                        throw new IllegalStateException("Unable to instantiate SectionHelperFactory: " + engineConfigClass, e);
                    }
                } else if (Types.isImplementorOf(engineConfigClass, Names.PARSER_HOOK, index)) {
                    try {
                        Class<?> parserHookClass = tccl.loadClass(engineConfigClass.toString());
                        ParserHook parserHook = (ParserHook) parserHookClass.getDeclaredConstructor().newInstance();
                        builder.addParserHook(parserHook);
                        LOGGER.debugf("ParserHook registered during template analysis: %s", engineConfigClass);
                    } catch (Exception e) {
                        throw new IllegalStateException("Unable to instantiate ParserHook: " + engineConfigClass, e);
                    }
                }
            }
        }

        builder.computeSectionHelper(name -> {
            // Create a dummy section helper factory for an unknown section that could be potentially registered at runtime
            return new SectionHelperFactory<SectionHelper>() {
                @Override
                public SectionHelper initialize(SectionInitContext context) {
                    return new SectionHelper() {
                        @Override
                        public CompletionStage<ResultNode> resolve(SectionResolutionContext context) {
                            return ResultNode.NOOP;
                        }
                    };
                }
            };

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the ParserHook has a public no-arg constructor that performs no build-time-unavailable initialization
  2. Inspect the 'Caused by' chain for the true root cause (ClassNotFoundException vs constructor exception)
  3. Keep the hook in a runtime module and match the Quarkus/Qute version used by the deployment module
  4. Verify the class truly implements io.quarkus.qute.ParserHook from the platform version

Example fix

// before
public class MyHook implements ParserHook {
    public MyHook(Config c) { ... } // requires args
}
// after
public class MyHook implements ParserHook {
    public MyHook() { }
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-instantiate the ParserHook to surface constructor problems early
Class<?> c = Class.forName("com.acme.MyParserHook", true, Thread.currentThread().getContextClassLoader());
if (!io.quarkus.qute.ParserHook.class.isAssignableFrom(c)) throw new IllegalStateException("Not a ParserHook");
c.getDeclaredConstructor().newInstance(); // fails early with the real cause

Prevention

When it happens

Trigger: analyzeTemplates detects a class implementing io.quarkus.qute.ParserHook among engine-config classes, loads it via tccl.loadClass() and calls getDeclaredConstructor().newInstance(); any Exception is wrapped in this IllegalStateException.

Common situations: ParserHook without a public no-arg constructor; hook whose constructor initializes something unavailable at build time; incompatible Qute API version on the classpath; TCCL not seeing the runtime class.

Related errors


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