karatelabs/karate · error · JsErrorException

. is not accessible (on )

Error message

. is not accessible (on )

What it means

Thrown by JavaUtils.invokeStatic when a matching static method exists but calling it raises IllegalAccessException — i.e. the method is not accessible from the calling context (non-public, or in a non-exported package under the JPMS module system). It is surfaced as a JS TypeError '.<name> is not accessible (on <TypeName>)'.

Solutions

  1. Use a public API equivalent of the internal method instead.
  2. If you must call it, add JVM flags like --add-opens / --add-exports for the relevant module/package.
  3. Downgrade expectations: check whether the library exposes a supported public wrapper.
  4. Confirm you're not targeting a class inside a sealed/final non-public package.

Example fix

// before
var Unsafe = Java.type('sun.misc.Unsafe');
var u = Unsafe.getUnsafe();
// after (public API)
var ByteBuffer = Java.type('java.nio.ByteBuffer');
var buf = ByteBuffer.allocateDirect(1024);
Defensive patterns

Strategy: try-catch

Validate before calling

var m = Clz.getClass().getMethod('methodName');
if (!java.lang.reflect.Modifier.isPublic(m.getModifiers())) karate.log('method not public, will fail under JPMS');

Try / catch

try { return Clz.internalMethod(); } catch (e) { if (String(e).indexOf('not accessible') !== -1) { return publicFallback(); } throw e; }

Prevention

When it happens

Trigger: Invoking a package-private/protected static method via JS interop, or calling into JDK-internal classes (e.g. sun.misc, jdk.internal.*) that JPMS does not export.

Common situations: JDK upgrade where previously reflective calls to internal APIs are now blocked by strong encapsulation (Java 9+); attempting to call internal library helpers not marked public.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JavaUtils.java:73

    static Object invokeStatic(Class<?> clazz, String name, Object[] args) {
        Method method = findMethod(clazz, name, args);
        if (method == null) {
            throw JsErrorException.typeError("." + name + " is not a function (called on " + jsTypeName(clazz) + ")");
        }
        try {
            return invoke(null, method, args);
        } catch (InvocationTargetException e) {
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException re) {
                throw re;
            }
            if (cause instanceof Error err) {
                throw err;
            }
            throw new RuntimeException(cause == null ? e.getMessage() : cause.getMessage(), cause);
        } catch (IllegalAccessException e) {
            throw JsErrorException.typeError("." + name + " is not accessible (on " + jsTypeName(clazz) + ")");
        }
    }

    static Object invoke(Object object, String name, Object[] args) {
        Method method = findMethod(object.getClass(), name, args);
        if (method == null) {
            throw JsErrorException.typeError("." + name + " is not a function (called on " + jsTypeName(object.getClass()) + ")");
        }
        try {
            return invoke(object, method, args);
        } catch (InvocationTargetException e) {
            // Unwrap so the underlying Java exception (and its message) reaches the caller
            // and can become a JS-catchable JsError at the host-function boundary.
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException re) {
                throw re;
            }
            if (cause instanceof Error err) {

View on GitHub (pinned to a22eb90246)