stanfordnlp/CoreNLP · error · IllegalStateException

Could not find SLF4J in your classpath

Error message

Could not find SLF4J in your classpath

What it means

Handlers.slff4j Thunk builds an SLF4JHandler via reflective MetaClass.create("edu.stanford.nlp.util.logging.SLF4JHandler"). When instantiation fails (typically ClassNotFoundException because the SLF4J API jar is absent), it rethrows as this IllegalStateException with the original exception as cause.

Solutions

  1. Add SLF4J to the classpath: Maven org.slf4j:slf4j-api plus a binding such as slf4j-simple or logback-classic.
  2. Inspect the cause chain (e.getCause()) to confirm the missing class is SLF4JHandler/SLF4J classes and fix packaging so it is included.
  3. Fall back to Handlers.output/stderr handler if SLF4J is intentionally not a dependency.
  4. If using a shaded jar, verify edu/stanford/nlp/util/logging/SLF4JHandler.class and slf4j classes survived the shading.

Example fix

// before (no slf4j dependency)
RedwoodConfiguration.empty().handlers(Handlers.slf4j).apply();
// after: add to pom.xml
// <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.x</version></dependency>
RedwoodConfiguration.empty().handlers(Handlers.slf4j).apply();
Defensive patterns

Strategy: fallback

Validate before calling

private static boolean slf4jAvailable() {
  try { Class.forName("org.slf4j.Logger"); return true; }
  catch (ClassNotFoundException e) { return false; }
}

Try / catch

try {
  config.handlers(Handlers.slf4j).apply();
} catch (IllegalStateException e) {
  if (e.getMessage().contains("Could not find SLF4J")) {
    config.handlers(Handlers.stderr).apply(); // graceful fallback
  } else throw e;
}

Prevention

When it happens

Trigger: Using RedwoodConfiguration Handlers.slff4j (e.g. log.handlers including slf4j in applyProperties) without org.slf4j:slf4j-api (and a concrete binding) on the classpath.

Common situations: Maven/Gradle project missing the slf4j dependency; fat jar built without SLF4J; runtime classpath (e.g. servlet container or spark-submit) lacking the library that compile-time classpath had.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/87101f6bbca94827. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/util/logging/RedwoodConfiguration.java:236

     * Consider using "output" instead, unless you really
     * want to log only to stderr now and forever in the future.
     */
    public static final Thunk stderr = (config, root) -> {
      Redwood.ConsoleHandler handler = Redwood.ConsoleHandler.err();
      handler.leftMargin = config.channelWidth;
      root.addChild(handler);
    };

    /**
     * Output to slf4j. This is a leaf node.
     */
    public static final Thunk slf4j = (config, root) -> {
      try {
        OutputHandler handler = MetaClass.create("edu.stanford.nlp.util.logging.SLF4JHandler").createInstance();
        handler.leftMargin = config.channelWidth;
        root.addChild(handler);
      } catch (Exception e) {
        throw new IllegalStateException("Could not find SLF4J in your classpath", e);
      }
    };

    /**
     * Output to java.util.Logging. This is a leaf node.
     */
    public static final Thunk javaUtil = (config, root) -> {
      try {
        OutputHandler handler = new JavaUtilLoggingHandler();
        handler.leftMargin = config.channelWidth;
        root.addChild(handler);
      } catch (Exception e) {
        throw new IllegalStateException("Could not find java.util.logging in your classpath", e);
      }
    };

    /**
     * Output to the default location specified by the output() method.

View on GitHub (pinned to 1b7edd19c4)