ruby-concurrency/concurrent-ruby · critical · RuntimeException

Could not initialize intrinsics

Error message

Could not initialize intrinsics

What it means

On first use, ConcurrentHashMapV8's static initializer reflects on sun.misc.Unsafe.theUnsafe (with setAccessible) to obtain memory-access intrinsics; if a SecurityManager denies it, it retries inside AccessController.doPrivileged. A PrivilegedActionException there is wrapped in RuntimeException("Could not initialize intrinsics"), class initialization fails, and later uses of the class degrade to NoClassDefFoundError. This file is the JRuby/Java half of the concurrent-ruby gem, so the failure surfaces when the JRuby extension loads under restrictive runtimes.

Source

Thrown at ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java:3858

     *
     * @return a sun.misc.Unsafe
     */
    private static sun.misc.Unsafe getUnsafe() {
        try {
            return sun.misc.Unsafe.getUnsafe();
        } catch (SecurityException se) {
            try {
                return java.security.AccessController.doPrivileged
                        (new java.security
                                .PrivilegedExceptionAction<sun.misc.Unsafe>() {
                            public sun.misc.Unsafe run() throws Exception {
                                java.lang.reflect.Field f = sun.misc
                                        .Unsafe.class.getDeclaredField("theUnsafe");
                                f.setAccessible(true);
                                return (sun.misc.Unsafe) f.get(null);
                            }});
            } catch (java.security.PrivilegedActionException e) {
                throw new RuntimeException("Could not initialize intrinsics",
                        e.getCause());
            }
        }
    }
}

View on GitHub (pinned to 0b88d5ff75)

Solutions

  1. Run on a standard JVM that ships sun.misc.Unsafe (HotSpot/OpenJDK/OpenJ9 — the normal JRuby target)
  2. Grant what the initializer needs in the policy: permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; (plus RuntimePermission "accessDeclaredMembers") for the extension jar's code base
  3. Remove or relax the SecurityManager if it is not actually required
  4. Use the bundled no-Unsafe build: the com.concurrent_ruby.ext.jsr166e.nounsafe.* sources avoid sun.misc.Unsafe entirely
  5. If you maintain a fork, replace getUnsafe() with a VarHandle/atomic-field-updater fallback

Example fix

// before: class init fails under a SecurityManager without reflective access
// -> RuntimeException: Could not initialize intrinsics (ExceptionInInitializerError)

// after: grant the permission in the .policy file
// grant codeBase "file:<path-to-concurrent-ruby-ext>" {
//   permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
//   permission java.lang.RuntimePermission "accessDeclaredMembers";
// };
// or deploy the nounsafe variant shipped in com.concurrent_ruby.ext.jsr166e.nounsafe
Defensive patterns

Strategy: validation

Validate before calling

static boolean unsafeAvailable() {
    try {
        java.lang.reflect.Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        return f.get(null) != null;
    } catch (Throwable t) {
        return false;
    }
}
// if (unsafeAvailable()) use the jsr166e classes; else fall back to
// java.util.concurrent.ConcurrentHashMap or the nounsafe build

Try / catch

try {
    Object m = Class.forName("com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8").newInstance();
} catch (ExceptionInInitializerError e) {
    Throwable c = e.getCause();
    if (c instanceof RuntimeException
            && "Could not initialize intrinsics".equals(((RuntimeException) c).getMessage())) {
        // fall back: platform ConcurrentHashMap or nounsafe build; restart if already loaded
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: First touch of ConcurrentHashMapV8 (map construction, JRuby loading the concurrent-ruby Java extension) when: the SecurityManager policy grants neither ReflectPermission("suppressAccessChecks") nor access to sun.misc.Unsafe.theUnsafe; the JVM's class library lacks sun.misc.Unsafe (Android/Dalvik, minimal runtimes); or an agent blocks setAccessible. The first failure surfaces as ExceptionInInitializerError wrapping this RuntimeException; subsequent touches throw NoClassDefFoundError.

Common situations: JRuby plus concurrent-ruby under a SecurityManager (sandboxed/embedded deployments, corporate policy files); nonstandard JVMs without sun.misc.Unsafe; environments where reflection-blocking agents were added. The gem ships a parallel nounsafe source tree (com.concurrent_ruby.ext.jsr166e.nounsafe) precisely to avoid this.

Related errors


AI-assisted analysis of ruby-concurrency/concurrent-ruby@0b88d5ff75 (2026-08-21). Data as JSON: /api/errors/a5fbba5c206f4de4. Report an issue: GitHub.