apache/hadoop · error · FileNotFoundException

webapps/{} not found in CLASSPATH

Error message

webapps/{} not found in CLASSPATH

What it means

getWebAppsPath() falls back to ClassLoader.getResource("webapps/" + appName) when the dev-mode directory is absent; a null result throws FileNotFoundException '<resource> not found in CLASSPATH'. It means no webapps/<appName> entry (directory or jar resource) is reachable from the classloader that loaded HttpServer2.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java:1361

   */
  protected String getWebAppsPath(String appName) throws FileNotFoundException {
    URL resourceUrl = null;
    File webResourceDevLocation = new File("src/main/webapps", appName);
    if (webResourceDevLocation.exists()) {
      LOG.info("Web server is in development mode. Resources "
          + "will be read from the source tree.");
      try {
        resourceUrl = webResourceDevLocation.getParentFile().toURI().toURL();
      } catch (MalformedURLException e) {
        throw new FileNotFoundException("Mailformed URL while finding the "
            + "web resource dir:" + e.getMessage());
      }
    } else {
      resourceUrl =
          getClass().getClassLoader().getResource("webapps/" + appName);

      if (resourceUrl == null) {
        throw new FileNotFoundException("webapps/" + appName +
            " not found in CLASSPATH");
      }
    }
    String urlString = resourceUrl.toString();
    return urlString.substring(0, urlString.lastIndexOf('/'));
  }

  /**
   * Get the port that the server is on
   * @return the port
   */
  @Deprecated
  public int getPort() {
    return ((ServerConnector)webServer.getConnectors()[0]).getLocalPort();
  }

  /**
   * Get the address that corresponds to a particular connector.

View on GitHub (pinned to 2add963021)

Solutions

  1. Ensure webapps/<appName> exists as a classpath resource: ship it inside your jar or as a directory next to hadoop-common's webapps
  2. Fix the appName passed to the builder (it must match the resource directory name)
  3. For shade assemblies, configure resource inclusion so 'webapps/**' is kept

Example fix

<!-- maven-shade-plugin: before, webapps resources dropped -->
<!-- after -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <configuration>
    <filters>
      <filter>
        <artifact>*:*</artifact>
        <excludes><exclude>META-INF/*.SF</exclude></excludes>
      </filter>
    </filters>
  </configuration>
</plugin>
<!-- plus ensure hadoop-common jar (containing webapps/) stays on the classpath unshaded -->
Defensive patterns

Strategy: validation

Validate before calling

if (Thread.currentThread().getContextClassLoader().getResource("webapps/" + appName) == null
    && !new File("src/main/webapps", appName).exists()) {
  throw new IllegalStateException("webapps/" + appName + " not on classpath; package it into the jar");
}

Try / catch

try {
  server.start();
} catch (FileNotFoundException e) {
  // message names the missing resource: verify packaging/classpath for that app
}

Prevention

When it happens

Trigger: Starting HttpServer2 with an appName whose webapps resources are not packaged (custom embedding with a made-up name); uber/shaded jars where the shade plugin dropped the webapps resource directory; a corrupted or trimmed hadoop-common jar in an unpacked distribution.

Common situations: Building fat jars for Hadoop-based services without resource inclusion; unit tests that construct HttpServer2 outside a full distribution; installing clusters with partially copied lib directories.

Related errors


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