grpc/grpc-java · error · UnsupportedOperationException

Subclass failed to hide static factory

Error message

Subclass failed to hide static factory

What it means

ForwardingServerBuilder is an abstract delegating wrapper around ServerBuilder. Its static forPort() is marked @DoNotCall and exists only to force subclasses to hide it with their own forPort(); calling the base implementation always throws UnsupportedOperationException since the wrapper cannot construct a concrete server builder.

Source

Thrown at api/src/main/java/io/grpc/ForwardingServerBuilder.java:43

import javax.annotation.Nullable;

/**
 * A {@link ServerBuilder} that delegates all its builder methods to another builder by default.
 *
 * @param <T> The type of the subclass extending this abstract class.
 * @since 1.34.0
 */
public abstract class ForwardingServerBuilder<T extends ServerBuilder<T>> extends ServerBuilder<T> {

  /** The default constructor. */
  protected ForwardingServerBuilder() {}

  /**
   * This method serves to force sub classes to "hide" this static factory.
   */
  @DoNotCall("Unsupported")
  public static ServerBuilder<?> forPort(int port) {
    throw new UnsupportedOperationException("Subclass failed to hide static factory");
  }

  /**
   * Returns the delegated {@code ServerBuilder}.
   */
  protected abstract ServerBuilder<?> delegate();

  @Override
  public T directExecutor() {
    delegate().directExecutor();
    return thisT();
  }

  @Override
  public T executor(@Nullable Executor executor) {
    delegate().executor(executor);
    return thisT();
  }

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Call the concrete builder's static factory, e.g. MyServerBuilder.forPort(9090), never ForwardingServerBuilder.forPort
  2. If you maintain a forwarding subclass, add your own static forPort(int) that builds via your delegate()
  3. For reflection-based bootstrap, resolve forPort on the concrete subclass Class, not the base wrapper

Example fix

// before
ServerBuilder<?> b = ForwardingServerBuilder.forPort(9090);
// after
ServerBuilder<?> b = MyServerBuilder.forPort(9090); // subclass's own static factory
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the concrete subclass shadows forPort before server bootstrap
if (MyServerBuilder.class.getMethod("forPort", int.class).getDeclaringClass()
    == io.grpc.ForwardingServerBuilder.class) {
  throw new IllegalStateException("Subclass must shadow forPort");
}

Try / catch

try {
  serverBuilder = MyServerBuilder.forPort(port);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("Subclass failed to hide static factory")) {
    serverBuilder = ServerBuilder.forPort(port);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling ForwardingServerBuilder.forPort(port) directly, or through a forwarding subclass that failed to declare its own static forPort(int). Also triggered by reflection or generic server-bootstrap code that resolves forPort on the base wrapper class.

Common situations: Generic server startup code reading a builder class name from configuration and invoking forPort on it when that class is (or extends) ForwardingServerBuilder; custom forwarding server builders missing the shadowing static method; IDE auto-import selecting the base class.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/0aa33fd3e2660d21. Report an issue: GitHub.