apache/pulsar · error · RuntimeException

User class constructor throws exception

Error message

User class constructor throws exception

What it means

If the user class's no-arg constructor itself throws an exception, newInstance() raises InvocationTargetException, which createInstance wraps in this RuntimeException with the constructor's exception as the cause. This is not a misuse of the helper — the class failed during its own initialization.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/Reflections.java:96

        Class<T> tCls = (Class<T>) theCls.asSubclass(xface);
        T result;
        try {
            @SuppressWarnings("unchecked") // safe: constructor cache is keyed by theCls which extends T
            Constructor<T> meth = (Constructor<T>) constructorCache.get(theCls);
            if (null == meth) {
                meth = tCls.getDeclaredConstructor();
                meth.setAccessible(true);
                constructorCache.put(theCls, meth);
            }
            result = meth.newInstance();
        } catch (InstantiationException ie) {
            throw new RuntimeException("User class must be concrete", ie);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("User class must have a no-arg constructor", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("User class must have a public constructor", e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("User class constructor throws exception", e);
        }
        return result;

    }

    /**
     * Create an instance of <code>userClassName</code> using provided <code>classLoader</code>.
     *
     * @param userClassName user class name
     * @param classLoader class loader to load the class.
     * @return the instance
     */
    public static Object createInstance(String userClassName,
                                        ClassLoader classLoader) {
        Class<?> theCls;
        try {
            theCls = Class.forName(userClassName, true, classLoader);
        } catch (ClassNotFoundException | NoClassDefFoundError cnfe) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Read the root cause via getCause() on this exception — fix the underlying constructor exception
  2. Remove side-effectful work from the constructor; defer to an init/initialize lifecycle method
  3. Validate required configuration/env before the framework instantiates the class

Example fix

// before
public MyFilter() { connection = connect(System.getenv("REQUIRED_URL")); } // NPE if unset
// after
public MyFilter() { }
public void initialize(Map<String,String> conf) { connection = connect(conf.get("url")); }
Defensive patterns

Strategy: try-catch

Validate before calling

// dry-run the constructor to surface its own failure early
Class<?> cls = Class.forName(className, true, classLoader);
cls.getDeclaredConstructor().newInstance(); // throws the real cause here first

Try / catch

try {
    T obj = Reflections.createInstance(className, XFace.class, classLoader);
} catch (RuntimeException e) {
    if (e.getMessage().equals("User class constructor throws exception")) {
        Throwable root = e;
        while (root.getCause() != null) { root = root.getCause(); }
        throw new IllegalStateException("Constructor of " + className + " failed: " + root, root);
    }
    throw e;
}

Prevention

When it happens

Trigger: Configuring a class whose constructor throws (static init failure, missing env var, failed connection in constructor, ExceptionInInitializerError path).

Common situations: Plugin constructor reads missing config/env; constructor touches unavailable services; static initializer throws (NoClassDefFoundError surfacing here).

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/1633a4b001e3ca1f. Report an issue: GitHub.