{"record":{"id":"612e68c40749ec13","repo":"ruby-concurrency/concurrent-ruby","slug":"could-not-initialize-intrinsics-612e68","errorCode":null,"errorMessage":"Could not initialize intrinsics","messagePattern":"Could not initialize intrinsics","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java","lineNumber":336,"sourceCode":"     *\n     * @return a sun.misc.Unsafe\n     */\n    private static sun.misc.Unsafe getUnsafe() {\n        try {\n            return sun.misc.Unsafe.getUnsafe();\n        } catch (SecurityException se) {\n            try {\n                return java.security.AccessController.doPrivileged\n                        (new java.security\n                                .PrivilegedExceptionAction<sun.misc.Unsafe>() {\n                            public sun.misc.Unsafe run() throws Exception {\n                                java.lang.reflect.Field f = sun.misc\n                                        .Unsafe.class.getDeclaredField(\"theUnsafe\");\n                                f.setAccessible(true);\n                                return (sun.misc.Unsafe) f.get(null);\n                            }});\n            } catch (java.security.PrivilegedActionException e) {\n                throw new RuntimeException(\"Could not initialize intrinsics\",\n                        e.getCause());\n            }\n        }\n    }\n\n}\n","sourceCodeStart":318,"sourceCodeEnd":343,"githubUrl":"https://github.com/ruby-concurrency/concurrent-ruby/blob/0b88d5ff75f69b3740c8f0868e76f833cb2fd45d/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java#L318-L343","documentation":"Striped64 (the basis of LongAdder/DoubleAdder striped counters) obtains sun.misc.Unsafe.theUnsafe in its static initializer exactly like ConcurrentHashMapV8 does, retrying under AccessController.doPrivileged when a SecurityManager interferes. Failure there is wrapped as RuntimeException(\"Could not initialize intrinsics\"), the class never initializes, and later touches throw NoClassDefFoundError.","triggerScenarios":"First touch of Striped64 — constructing a LongAdder/DoubleAdder or any counter built on cell-striping — when the security policy blocks reflection on sun.misc.Unsafe.theUnsafe, or the runtime (Android/Dalvik, minimal JVMs) has no sun.misc.Unsafe. Initial failure appears as ExceptionInInitializerError; subsequent uses fail with NoClassDefFoundError.","commonSituations":"JRuby deployments of concurrent-ruby in sandboxed or policy-file-managed environments; nonstandard JVMs lacking sun.misc.Unsafe; runtimes with reflection-blocking agents. The gem's nounsafe build of Striped64 replaces Unsafe with AtomicIntegerFieldUpdater/AtomicLongFieldUpdater for exactly this case.","solutions":["Run on a standard JVM that ships sun.misc.Unsafe (HotSpot/OpenJDK/OpenJ9)","Grant the initializer's requirements in the policy: ReflectPermission \"suppressAccessChecks\" (plus RuntimePermission \"accessDeclaredMembers\") for the extension jar","Remove or relax the SecurityManager if feasible","Use the bundled nounsafe Striped64 (com.concurrent_ruby.ext.jsr166e.nounsafe), which relies on atomic field updaters instead of Unsafe","If you maintain a fork, add a VarHandle/atomic-updater fallback to getUnsafe()"],"exampleFix":"// before: LongAdder never loads -> Striped64.<clinit> fails\n// -> RuntimeException: Could not initialize intrinsics\n\n// after: grant the permission in the .policy file\n// grant codeBase \"file:<path-to-concurrent-ruby-ext>\" {\n//   permission java.lang.reflect.ReflectPermission \"suppressAccessChecks\";\n//   permission java.lang.RuntimePermission \"accessDeclaredMembers\";\n// };\n// or use the nounsafe build (atomic field updaters, no sun.misc.Unsafe)","handlingStrategy":"validation","validationCode":"static boolean unsafeAvailable() {\n    try {\n        java.lang.reflect.Field f = sun.misc.Unsafe.class.getDeclaredField(\"theUnsafe\");\n        f.setAccessible(true);\n        return f.get(null) != null;\n    } catch (Throwable t) {\n        return false;\n    }\n}\n// probe once at startup; if false, avoid LongAdder/Striped64-backed\n// counters and use AtomicLong or the nounsafe build instead","typeGuard":null,"tryCatchPattern":"try {\n    Object adder = Class.forName(\"com.concurrent_ruby.ext.jsr166e.LongAdder\").newInstance();\n} catch (ExceptionInInitializerError e) {\n    Throwable c = e.getCause();\n    if (c instanceof RuntimeException\n            && \"Could not initialize intrinsics\".equals(((RuntimeException) c).getMessage())) {\n        // fall back to AtomicLong-based counters; Striped64 will stay broken (NoClassDefFoundError)\n    } else {\n        throw e;\n    }\n}","preventionTips":["Probe sun.misc.Unsafe availability before first counter use in locked-down environments","Grant ReflectPermission \\\"suppressAccessChecks\\\" to the extension jar in the policy","Prefer the nounsafe Striped64 build (atomic field updaters) where Unsafe is unavailable","After one init failure the class never loads again in that JVM — restart after fixing the policy"],"tags":["java","sun-misc-unsafe","security-manager","jvm","class-init","concurrent-ruby","jruby"],"backgroundTag":"sun-misc-unsafe-unavailable","analyzedSha":"0b88d5ff75f69b3740c8f0868e76f833cb2fd45d","analyzedAt":"2026-08-21T20:12:56.291Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}