apache/hadoop · error · UnsupportedOperationException

Param class [{0}] does not have default constructor

Error message

Param class [{0}] does not have default constructor

What it means

ParametersProvider.newParam (ParametersProvider.java:53) instantiates every registered Param class reflectively via paramClass.newInstance(); if the class lacks an accessible no-argument constructor (non-static inner class, non-public class, abstract class, or only parameterized constructors) it throws UnsupportedOperationException("Param class [...] does not have default constructor"). It fires at request-processing time while building the Parameters object for the incoming operation, turning a wiring bug into a runtime 500.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/ParametersProvider.java:53

@InterfaceAudience.Private
public class ParametersProvider {

  private String driverParam;
  private Class<? extends Enum> enumClass;
  private Map<Enum, Class<Param<?>>[]> paramsDef;

  public ParametersProvider(String driverParam, Class<? extends Enum> enumClass,
      Map<Enum, Class<Param<?>>[]> paramsDef) {
    this.driverParam = driverParam;
    this.enumClass = enumClass;
    this.paramsDef = paramsDef;
  }

  private Param<?> newParam(Class<Param<?>> paramClass) {
    try {
      return paramClass.newInstance();
    } catch (Exception ex) {
      throw new UnsupportedOperationException(
        MessageFormat.format("Param class [{0}] does not have default constructor",
            paramClass.getName()));
    }
  }

  public Parameters get(HttpServletRequest request) {
    Map<String, List<Param<?>>> map = new HashMap<>();

    Map<String, String[]> queryString = request.getParameterMap();
    String str = null;
    if(queryString.containsKey(driverParam)) {
      str = queryString.get(driverParam)[0];
    }
    if (str == null) {
      throw new IllegalArgumentException(
        MessageFormat.format("Missing Operation parameter [{0}]",
                             driverParam));
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Make every Param subclass a public static class with a public no-arg constructor — mirror the params in HttpFSParametersProvider.
  2. Re-add the no-arg constructor when a parameterized one is introduced.
  3. Move inner param classes to top level or mark them static.
  4. Add a startup/registration smoke test that instantiates every registered param class.

Example fix

// before
public class MyParams {
  class OffsetParam extends IntegerParam { // inner class: newInstance() fails
    OffsetParam(int d) { super("offset", d); }
  }
}

// after
public static class OffsetParam extends IntegerParam {
  public OffsetParam() { super("offset", 1); } // public no-arg constructor
}
Defensive patterns

Strategy: validation

Validate before calling

for (Class<Param<?>> c : paramsDef.get(op)) {
  if (!java.lang.reflect.Modifier.isPublic(c.getModifiers())) throw new IllegalStateException(c + " must be public");
  try { c.getConstructor(); } catch (NoSuchMethodException e) {
    throw new IllegalStateException(c + " needs a public no-arg constructor");
  }
}

Type guard

static boolean hasPublicNoArgCtor(Class<?> c) {
  return java.lang.reflect.Modifier.isPublic(c.getModifiers())
      && java.util.Arrays.stream(c.getConstructors()).anyMatch(ctor -> ctor.getParameterCount() == 0);
}

Try / catch

try {
  parameters = provider.get(request);
} catch (UnsupportedOperationException ex) {
  // server wiring bug: a registered Param class is not instantiable
  LOG.error("Param registration broken", ex);
  return serverError();
}

Prevention

When it happens

Trigger: Extending the httpfs wsrs framework with a custom Param subclass that is (a) a non-static inner class, (b) only defines constructors with arguments, or (c) is package-private or abstract, then registering it in the provider's paramsDef map. The first matching request hits newParam and throws.

Common situations: A fork adds a WebHDFS-style operation whose param class was written as an inner class; a refactor makes a static subclass non-static; someone adds an args-taking constructor and deletes the no-arg one; JDK visibility changes make the constructor inaccessible.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/0bff877c3dbcb0ef. Report an issue: GitHub.