java-native-access/jna · error · IllegalArgumentException

Could not access instance of

Error message

Could not access instance of <cls> (<cause>)

What it means

Native's library-registration path reads the mapped library instance from a static field of the interface class via reflection (field.get(null)). If any reflective access fails (security manager, inaccessible field, IllegalAccessException, etc.), JNA wraps the exception in an IllegalArgumentException: 'Could not access instance of <cls> (<cause>)'.

Solutions

  1. Ensure the mapping interface has a public static final field holding the loaded library instance (convention: INSTANCE).
  2. Remove the SecurityManager or add reflective-access permissions (ReflectPermission) for JNA.
  3. Verify the class passed to the registration API actually is the library interface with a static instance.
  4. Catch the IllegalArgumentException and inspect getCause() to see the underlying reflection failure.

Example fix

// before
public interface FooLib { // no public static instance accessible
    FooLib LIB = Native.load("foo", FooLib.class); // package-private? non-standard name
}
// after
public interface FooLib extends Library {
    FooLib INSTANCE = Native.load("foo", FooLib.class); // public static field JNA can read
}
Defensive patterns

Strategy: try-catch

Validate before calling

Field f = mappingClass.getDeclaredField("INSTANCE");
if (!Modifier.isStatic(f.getModifiers()) || !Modifier.isPublic(f.getModifiers())) {
    throw new IllegalStateException("library INSTANCE field must be public static");
}

Try / catch

try {
    registerLibrary(mappingClass);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("Reflective access to " + mappingClass
        + " failed: " + e.getMessage(), e.getCause());
}

Prevention

When it happens

Trigger: Calling Native.loadLibrary(Native.getLibraryClass(...)-style registration) / Native.synchronizedLibrary-style helpers where the static INSTANCE/WCE_INSTANCE-style field cannot be reflectively read — e.g. a non-static field, null value handled elsewhere, or a SecurityManager denying reflection.

Common situations: Running under a SecurityManager or restricted environment (app server, webstart) blocking reflective access; the interface was modified so the expected static field no longer exists or is not accessible; custom classloaders returning odd classes.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/500393386d5253e0. Report an issue: GitHub.

Appendix: source

Thrown at src/com/sun/jna/Native.java:767

     * Expects that lock on libraries is already held
     */
    private static void loadLibraryInstance(Class<?> cls) {
        if (cls != null && !libraries.containsKey(cls)) {
            try {
                Field[] fields = cls.getFields();
                for (int i=0;i < fields.length;i++) {
                    Field field = fields[i];
                    if (field.getType() == cls
                        && Modifier.isStatic(field.getModifiers())) {
                        // Ensure the field gets initialized by reading it
                        field.setAccessible(true); // interface might be private
                        libraries.put(cls, new WeakReference<>(field.get(null)));
                        break;
                    }
                }
            }
            catch (Exception e) {
                throw new IllegalArgumentException("Could not access instance of "
                                                   + cls + " (" + e + ")");
            }
        }
    }

    /**
     * Find the library interface corresponding to the given class.  Checks
     * all ancestor classes and interfaces for a declaring class which
     * implements {@link Library}.
     * @param cls The given class
     * @return The enclosing class
     */
    static Class<?> findEnclosingLibraryClass(Class<?> cls) {
        if (cls == null) {
            return null;
        }
        // Check for direct-mapped libraries, which won't necessarily
        // implement com.sun.jna.Library.

View on GitHub (pinned to d036ad9781)