{"record":{"id":"ed2d9986c55ffebc","repo":"oracle/graal","slug":"illegal-access-linking-method-jdk-jfr-internal-ev","errorCode":null,"errorMessage":"illegal access linking method 'jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long)'","messagePattern":"illegal access linking method 'jdk\\.jfr\\.internal\\.event\\.EventWriterFactory\\.getEventWriter\\(long\\)'","errorType":"exception","errorClass":"IllegalAccessError","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/classfile/ClassfileConstantPool.java","lineNumber":179,"sourceCode":"    @Override\n    public JavaMethod lookupMethod(int index, int opcode) {\n        if (opcode == Bytecodes.INVOKEDYNAMIC) {\n            throw new GraalError(\"INVOKEDYNAMIC not supported by\" + ClassfileBytecodeProvider.class.getSimpleName());\n        }\n        return get(ExecutableRef.class, index).resolve(this, opcode);\n    }\n\n    @Override\n    public JavaMethod lookupMethod(int index, int opcode, ResolvedJavaMethod caller) {\n        if (opcode == Bytecodes.INVOKEDYNAMIC) {\n            throw new GraalError(\"INVOKEDYNAMIC not supported by\" + ClassfileBytecodeProvider.class.getSimpleName());\n        }\n        ResolvedJavaMethod result = get(ExecutableRef.class, index).resolve(this, opcode);\n        if (result != null && result.getName().equals(\"getEventWriter\") && result.getDeclaringClass().getName().equals(\"Ljdk/jfr/internal/event/EventWriterFactory;\")) {\n            // Only JFR transformed methods can call\n            // jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long)\n            // and this ClassfileBytecode will never be used to load such a class.\n            throw new IllegalAccessError(\"illegal access linking method 'jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long)'\");\n        }\n        return result;\n    }\n\n    @Override\n    public List<BootstrapMethodInvocation> lookupBootstrapMethodInvocations(boolean invokeDynamic) {\n        throw GraalError.unimplementedOverride(); // ExcludeFromJacocoGeneratedReport\n    }\n\n    @Override\n    public JavaType lookupType(int index, int opcode) {\n        return get(ClassRef.class, index).resolve(this);\n    }\n\n    @Override\n    public JavaType lookupReferencedType(int index, int opcode) {\n        switch (opcode) {\n            case Bytecodes.CHECKCAST:","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/classfile/ClassfileConstantPool.java#L161-L197","documentation":"lookupMethod special-cases jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long): that internal method may only be linked from JFR-instrumented bytecode, which this provider never parses. Resolving it through ClassfileBytecodePool therefore throws IllegalAccessError immediately, mirroring the JVM's access check and failing fast instead of producing an invalid linkage.","triggerScenarios":"Bytecode parsed by ClassfileBytecodeProvider resolves a call whose constant-pool target is EventWriterFactory.getEventWriter(long).","commonSituations":"Replacement/snippet code (or copied JFR internals) attempting to call the internal event-writer factory directly; using jdk.jfr.internal types instead of the public jdk.jfr API.","solutions":["Do not call jdk.jfr.internal.* from your own code; use the public jdk.jfr API (Event, EventFactory, Recording).","If you copied HotSpot/JFR-internal source into replacements, remove or stub the getEventWriter call path."],"exampleFix":"// before\nEventWriter w = EventWriterFactory.getEventWriter(eventStruct); // internal API\n\n// after\nMyEvent ev = new MyEvent(); // extends jdk.jfr.Event (public API)\nev.commit();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    JavaMethod m = pool.lookupMethod(index, opcode, caller);\n} catch (IllegalAccessError e) {\n    // A resolution attempt on jdk.jfr.internal EventWriterFactory.getEventWriter\n    // means internal JFR APIs leaked into parsed bytecode; fix the caller, don't retry\n    throw new IllegalStateException(\"Internal JFR API referenced from parsed bytecode\", e);\n}","preventionTips":["Depend only on the public jdk.jfr API; treat jdk.jfr.internal as off-limits (it is not portable and not linkable here).","Add a dependency/bytecode rule (e.g. jdeps or ArchUnit) forbidding imports of jdk.jfr.internal.*."],"tags":["graal","jfr","internal-api","illegal-access","security"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}