{"record":{"id":"aed8b42457dc8d08","repo":"oracle/graal","slug":"onshutdowncallback-value-does-not-have-classname","errorCode":null,"errorMessage":"OnShutdownCallback value does not have <classname>.<method name> format: %s","messagePattern":"OnShutdownCallback value does not have <classname>\\.<method name> format: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java","lineNumber":460,"sourceCode":"            for (Group group : snippetCounterGroups) {\n                TTY.out().out().println(group);\n            }\n        }\n        BenchmarkCounters.shutdown(runtime(), options, runtimeStartTime);\n\n        outputDirectory.close();\n\n        CompilationPrinter.close();\n\n        LibGraalSupport libgraal = LibGraalSupport.INSTANCE;\n        if (libgraal != null) {\n            String callback = HotSpotGraalCompiler.Options.OnShutdownCallback.getValue(options);\n            String callbackClassName = null;\n            String callbackMethodName = null;\n            if (callback != null) {\n                int lastDot = callback.lastIndexOf('.');\n                if (lastDot < 1 || lastDot == callback.length() - 1) {\n                    throw new IllegalArgumentException(HotSpotGraalCompiler.Options.OnShutdownCallback.getName() + \" value does not have <classname>.<method name> format: \" + callback);\n                }\n                callbackClassName = callback.substring(0, lastDot);\n                callbackMethodName = callback.substring(lastDot + 1);\n            }\n            libgraal.shutdown(callbackClassName, callbackMethodName);\n        }\n    }\n\n    void clearMetrics() {\n        metricValues.clear();\n    }\n\n    private final boolean bootstrapJVMCI;\n    private boolean bootstrapFinished;\n\n    public void notifyBootstrapFinished() {\n        bootstrapFinished = true;\n    }","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java#L442-L478","documentation":"At shutdown, if libgraal is in use and HotSpotGraalCompiler.Options.OnShutdownCallback is set, HotSpotGraalRuntime splits the value at the last dot into class and method names. A value with no usable dot (lastDot < 1, or a trailing dot with no method) throws IllegalArgumentException naming the expected <classname>.<method name> format.","triggerScenarios":"Setting -Dgraal.OnShutdownCallback=myscript (no dot), '.mymethod' (empty class), or 'com.foo.Bar.' (empty method) and shutting down a JVM running libgraal; only then is the callback string parsed via lastIndexOf('.') and validated.","commonSituations":"Using the option to invoke cleanup on shutdown but passing a bare method name or class only; shell quoting/variable expansion eating part of the value; copying the option from docs that omitted the method part.","solutions":["Set the value as a fully qualified class plus method: com.foo.ShutdownHook.cleanup (method must be reachable as declared)","Verify the exact string with -Xlog or by printing the property before shutdown","If no callback is needed, unset the option entirely"],"exampleFix":"# before\n-Dgraal.OnShutdownCallback=cleanup\n\n# after\n-Dgraal.OnShutdownCallback=com.foo.ShutdownHooks.cleanup","handlingStrategy":"validation","validationCode":"static boolean validCallback(String s) {\n    if (s == null) return true;\n    int d = s.lastIndexOf('.');\n    return d >= 1 && d < s.length() - 1; // class.method, both non-empty\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass fully-qualified <classname>.<method> to OnShutdownCallback","Test shutdown once after setting the option","Avoid building the value from unvalidated shell variables"],"tags":["graal-compiler","options","shutdown","libgraal","validation"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}