jenkinsci/jenkins · error · AbstractMethodError

Plugin class ' ' does not override either overload of the…

Error message

Plugin class '{getClass().getName()}' does not override either overload of the decorateLogger method.

What it means

AbstractMethodError thrown by the deprecated ConsoleLogFilter.decorateLogger(AbstractBuild, OutputStream) when a subclass overrides neither that method nor decorateLogger(Run, OutputStream). Util.isOverridden detects the missing Run-based override, so the old method cannot forward and aborts. The class is documented as requiring the Run overload to be implemented.

Solutions

  1. Override decorateLogger(Run, OutputStream) in the subclass.
  2. If you must support pre-1.632 cores, override both overloads.
  3. Audit ConsoleLogFilter subclasses after a core upgrade.

Example fix

// before
public class MyFilter extends ConsoleLogFilter { }
// after
public class MyFilter extends ConsoleLogFilter {
    @Override
    public OutputStream decorateLogger(Run build, OutputStream logger)
            throws IOException, InterruptedException {
        return new MyStream(logger);
    }
}
Defensive patterns

Strategy: validation

Validate before calling

if (!Util.isOverridden(ConsoleLogFilter.class, filter.getClass(),
        "decorateLogger", Run.class, OutputStream.class)) {
    // subclass must override the Run overload
}

Try / catch

try { filter.decorateLogger(build, out); }
catch (AbstractMethodError e) { /* subclass overrides neither overload */ }

Prevention

When it happens

Trigger: A plugin's ConsoleLogFilter extension that overrides neither decorateLogger overload, invoked through the legacy AbstractBuild API (older core or another plugin).

Common situations: Plugin compiled against an old core; an empty/stub ConsoleLogFilter subclass; core upgraded past 1.632 where the Run overload became the expected one.

Related errors


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

Appendix: source

Thrown at core/src/main/java/hudson/console/ConsoleLogFilter.java:72

 */
public abstract class ConsoleLogFilter implements ExtensionPoint {
    /**
     * Called on the start of each build, giving extensions a chance to intercept
     * the data that is written to the log.
     *
     * @throws AbstractMethodError
     *     when a plugin overrides neither this method nor {@link #decorateLogger(Run, OutputStream)}.
     *
     * @deprecated as of 1.632. Use {@link #decorateLogger(Run, OutputStream)}
     */
    @Deprecated
    public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) throws IOException, InterruptedException {
        if (Util.isOverridden(ConsoleLogFilter.class, getClass(), "decorateLogger", Run.class, OutputStream.class)) {
            // old client calling newer implementation. forward the call.
            return decorateLogger((Run) build, logger);
        } else {
            // happens only if the subtype fails to override either decorateLogger method
            throw new AbstractMethodError("Plugin class '" + this.getClass().getName() + "' does not override " +
                    "either overload of the decorateLogger method.");
        }
    }

    /**
     * Called on the start of each build, giving extensions a chance to intercept
     * the data that is written to the log.
     *
     * <p>
     * Even though this method is not marked 'abstract', this is the method that must be overridden
     * by extensions.
     */
    public OutputStream decorateLogger(Run build, OutputStream logger) throws IOException, InterruptedException {
        // this implementation is backward compatibility thunk in case subtypes only override the
        // old signature (AbstractBuild,OutputStream)

        if (build instanceof AbstractBuild) {
            // maybe the plugin implements the old signature.

View on GitHub (pinned to 2e228ff40b)