jenkinsci/jenkins · error · RuntimeException

@PostConstruct %s

Error message

@PostConstruct %s

What it means

Thrown by GuiceExtensionResolver.onProvision when invoking a @PostConstruct-annotated method on a freshly created extension instance throws. Jenkins collects all @PostConstruct methods across the class hierarchy and invokes them after Guice provisioning; any reflective invocation failure is wrapped in a RuntimeException naming the method.

Source

Thrown at core/src/main/java/hudson/ExtensionFinder.java:640

                final Set<Class<?>> interfaces = ClassUtils.getAllInterfacesAsSet(instance);

                while (c != Object.class) {
                    Arrays.stream(c.getDeclaredMethods())
                            .map(m -> getMethodAndInterfaceDeclarations(m, interfaces))
                            .flatMap(Collection::stream)
                            .filter(m -> m.getAnnotation(PostConstruct.class) != null || m.getAnnotation(javax.annotation.PostConstruct.class) != null)
                            .findFirst()
                            .ifPresent(methods::addFirst);
                    c = c.getSuperclass();
                }

                for (Method postConstruct : methods) {
                    try {
                        postConstruct.setAccessible(true);
                        postConstruct.invoke(instance);
                    } catch (final Exception e) {
                        throw new RuntimeException(String.format("@PostConstruct %s", postConstruct), e);
                    }
                }
            }
        }
    }

    /**
     * Returns initial {@link Method} as well as all matching ones found in interfaces.
     * This allows to introspect metadata for a method which is both declared in parent class and in implemented
     * interface(s). {@code interfaces} typically is obtained by {@link ClassUtils#getAllInterfacesAsSet}
     */
    Collection<Method> getMethodAndInterfaceDeclarations(Method method, Collection<Class<?>> interfaces) {
        final List<Method> methods = new ArrayList<>();
        methods.add(method);

        // we search for matching method by iteration and comparison vs getMethod to avoid repeated NoSuchMethodException
        // being thrown, while interface typically only define a few set of methods to check.
        interfaces.stream()

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Read the cause and the method name in the message to locate the failing @PostConstruct.
  2. Make the @PostConstruct method defensive: try/catch around risky init, or move lazy logic.
  3. Ensure the method is non-private, takes no arguments, and returns void per JSR-250.
  4. Verify any singleton it depends on is registered and loaded first.

Example fix

// before
@PostConstruct
public void init() { this.conn = ds.getConnection(); } // throws if DB down
// after
@PostConstruct
public void init() {
    try { this.conn = ds.getConnection(); }
    catch (SQLException e) { LOGGER.log(Level.WARNING, "no DB", e); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

static boolean isPostConstructSafe(Method m) {
    return m.getParameterCount() == 0 && m.getReturnType() == void.class;
}

Try / catch

try {
    // extension provisioning that runs @PostConstruct
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("@PostConstruct")) {
        // defensive: log and continue, or mark the extension failed
    } else throw e;
}

Prevention

When it happens

Trigger: A @PostConstruct method on an extension throws (NPE, resource init failure, denied permission); the method is not accessible and setAccessible fails; the method requires arguments (illegal) causing IllegalArgumentException; provisioning order means a dependency is not ready.

Common situations: Extension's @PostConstruct opens a DB/file/network resource that is unavailable; extension assumes another singleton is already initialized but ordering differs; @PostConstruct added to a private method that the JVM refuses to make accessible under a strict module path.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/f3ffdd28222dd9e1. Report an issue: GitHub.