{"record":{"id":"6c4eec724c8434c3","repo":"karatelabs/karate","slug":"cause-message","errorCode":null,"errorMessage":"<cause message>","messagePattern":"<cause message>","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JavaType.java","lineNumber":59,"sourceCode":"        // child loader (e.g. JUnit Platform Console Launcher's --cp loader)\n        // are visible. Class.forName(name) uses the caller's defining loader\n        // (this bundle's), which can't see those classes. Fall back to that\n        // loader if the TCCL isn't set or doesn't have the class.\n        Class<?> resolved = null;\n        ClassNotFoundException last = null;\n        ClassLoader tccl = Thread.currentThread().getContextClassLoader();\n        if (tccl != null) {\n            try {\n                resolved = Class.forName(className, true, tccl);\n            } catch (ClassNotFoundException e) {\n                last = e;\n            }\n        }\n        if (resolved == null) {\n            try {\n                resolved = Class.forName(className);\n            } catch (ClassNotFoundException e) {\n                throw new RuntimeException(last != null ? last : e);\n            }\n        }\n        this.clazz = resolved;\n    }\n\n    @Override\n    public Object construct(Object[] args) {\n        return JavaUtils.construct(clazz, args);\n    }\n\n    @Override\n    public Object invokeMethod(String name, Object[] args) {\n        return JavaUtils.convertIfArray(JavaUtils.invokeStatic(clazz, name, args));\n    }\n\n    @Override\n    public Object getProperty(String name) {\n        return JavaUtils.convertIfArray(JavaUtils.getStatic(clazz, name));","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JavaType.java#L41-L77","documentation":"JavaType resolves a Java class by name; when Class.forName fails it throws a RuntimeException whose message/cause is the last ClassNotFoundException (or a previously captured resolution failure). It means the requested Java class is not on the classpath.","triggerScenarios":"`Java.type('some.Class')` (or JavaType construction) with a class name that has no import alias match and cannot be loaded by Class.forName.","commonSituations":"Typo in fully-qualified class name; dependency jar missing from the test classpath; class present only in a different Maven module/profile; package renames across library versions.","solutions":["Verify the fully-qualified class name for typos and correct package","Add the artifact containing the class to the test classpath (pom.xml/gradle dependency)","Check the cause chain — `last` may point to an earlier, more specific resolution failure","Use an import alias (karate.configure / Java import binding) if the class is available under another name"],"exampleFix":"// before\nvar Tcp = Java.type('com.example.tcp.Client'); // ClassNotFoundException\n// after\n// add the dependency, then:\nvar Tcp = Java.type('com.example.tcp.Client'); // resolves","handlingStrategy":"try-catch","validationCode":"try { Class.forName(className); } catch (ClassNotFoundException e) { /* fail fast with clear message */ }","typeGuard":null,"tryCatchPattern":"try {\n  var T = Java.type('com.example.Client');\n} catch (e) {\n  karate.log('class not on classpath:', 'com.example.Client');\n}","preventionTips":["Use fully-qualified class names exactly as declared","Keep the dependency that provides the class in the same Maven module/profile as the tests","Grep the build file for the artifact before using a new Java.type"],"tags":["java-interop","classpath","class-not-found","dependency"],"backgroundTag":"class-not-found","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}