karatelabs/karate · error · JsErrorException

Java.type: class not found

Error message

Java.type: class not found: {className}

What it means

Java.type('X') could not resolve the class name through the type bridge: bridge.forType(className) returned null. Karate surfaces this immediately as a TypeError so the failure is not silently propagated and later misreported as 'cannot read properties of null'.

Solutions

  1. Verify the exact fully-qualified class name, using '$' for nested classes (com.example.Outer$Inner).
  2. Add the jar/dependency containing the class to the classpath (pom.xml, build.gradle, or -cp).
  3. Confirm with `karate.log(Java.type('com.example.Foo'))` on a class known to exist to validate classpath setup.
  4. Check that the class is visible to the same classloader Karate runs under (IDE module vs Maven test classpath).

Example fix

// before
var Cls = Java.type('com.example.util.Paylod'); // typo
// after
var Cls = Java.type('com.example.util.Payload');
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm the dependency is on the classpath before running the feature (e.g. mvn dependency:tree | grep my-lib)

Try / catch

var Cls;
try { Cls = Java.type('com.example.Foo'); } catch (e) { if (String(e).indexOf('class not found') !== -1) { karate.abort('missing dependency for Foo'); } else { throw e; } }

Prevention

When it happens

Trigger: Java.type('com.example.Missing') where the class does not exist, the FQN is misspelled, the class is in a jar not on the classpath, or an inner class is referenced with a dot instead of '$'.

Common situations: Typos in fully-qualified names; running a feature that needs a dependency not declared in the pom/build; class present in a different classloader (e.g. IDE vs CLI); migrating code between projects with different dependencies.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/53d419a59e7e1ad6. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsJava.java:50

            throw new RuntimeException("java bridge not enabled");
        }
        this.bridge = bridge;
    }

    @Override
    public Object jsGet(String name) {
        return switch (name) {
            case "type" -> (JsInvokable) args -> {
                String className = (String) args[0];
                // forType() returns null on ClassNotFoundException — that
                // null-as-sentinel contract is needed by PropertyAccess for
                // the dotted-FQN probe, so we keep it. But here the script
                // explicitly asked for this class; a null result must surface
                // as a real error rather than silently propagating and
                // failing later as "cannot read properties of null".
                ExternalAccess type = bridge.forType(className);
                if (type == null) {
                    throw JsErrorException.typeError("Java.type: class not found: " + className);
                }
                return type;
            };
            case "to" -> (JsInvokable) args -> {
                if (args[0] instanceof ExternalAccess ja) {
                    return ja.getJavaValue();
                }
                // TODO regex, functions, lambdas
                return null;
            };
            default -> throw JsErrorException.typeError("no such api on Java: " + name);
        };
    }

}

View on GitHub (pinned to a22eb90246)