{"record":{"id":"a9a5d0774e69941e","repo":"apache/cassandra","slug":"mbeanserver-already-initialized","errorCode":null,"errorMessage":"MBeanServer already initialized","messagePattern":"MBeanServer already initialized","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java","lineNumber":187,"sourceCode":"        {\n            if (\"getMBeanServer\".equals(methodName))\n                throw new SecurityException(\"Access denied\");\n\n            // Corresponds to MBeanServer.invoke\n            if (methodName.equals(\"invoke\") && args.length == 4)\n                checkVulnerableMethods(args);\n\n            // Allow setMBeanServer iff performed on behalf of the connector server itself\n            if ((\"setMBeanServer\").equals(methodName))\n            {\n                if (subject != null)\n                    throw new SecurityException(\"Access denied\");\n\n                if (args[0] == null)\n                    throw new IllegalArgumentException(\"Null MBeanServer\");\n\n                if (mbs != null)\n                    throw new IllegalArgumentException(\"MBeanServer already initialized\");\n\n                mbs = (MBeanServer) args[0];\n                return null;\n            }\n\n            if (authorize(subject, methodName, args))\n            {\n                Object invoke = invoke(method, args);\n                listener.onInvocation(subject, method, args);\n                return invoke;\n            }\n\n            throw new SecurityException(\"Access Denied\");\n        }\n        catch (Exception e)\n        {\n            listener.onFailure(subject, method, args, e);\n            throw e;","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/auth/jmx/AuthorizationProxy.java#L169-L205","documentation":"The proxy stores its single MBeanServer reference in the field mbs and treats it as write-once. A second setMBeanServer call after initialization throws IllegalArgumentException(\"MBeanServer already initialized\") at line 187. This protects against hot-swapping the server out from under live connections and cached authorization state.","triggerScenarios":"setMBeanServer called with subject == null and a non-null server, while AuthorizationProxy.mbs has already been set by an earlier setMBeanServer during connector startup.","commonSituations":"Creating a second JMXConnectorServer that reuses the same proxy; restarting the connector within the same JVM without recreating the proxy; test suites that bootstrap Cassandra's JMX setup multiple times in one JVM.","solutions":["Do not call setMBeanServer more than once per proxy; construct a fresh AuthorizationProxy for each new connector server.","If re-initializing in tests, build a new proxy instance (or reset mbs via the test-visible setter) before calling setMBeanServer again.","Reuse the already-initialized MBeanServer instead of trying to replace it."],"exampleFix":"// before\nAuthorizationProxy proxy = new AuthorizationProxy(...); // created earlier and already set\nproxy.setMBeanServer(newServer); // IllegalStateException/IAX: already initialized\n// after\nAuthorizationProxy proxy = new AuthorizationProxy(); // fresh instance per connector\nproxy.setMBeanServer(newServer);","handlingStrategy":"validation","validationCode":"// guard at the call site: setMBeanServer is write-once per proxy\nif (proxyAlreadyInitialized)\n    throw new IllegalStateException(\"Create a new AuthorizationProxy instead of re-initializing the existing one\");","typeGuard":null,"tryCatchPattern":"try {\n    proxy.setMBeanServer(server);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"already initialized\")) {\n        logger.info(\"MBeanServer already set; reusing existing instance\");\n    } else throw e;\n}","preventionTips":["Create a fresh AuthorizationProxy per JMXConnectorServer lifecycle.","In test suites, recreate proxy instances between Cassandra bootstrap cycles rather than reusing them.","Treat the proxy's mbs field as write-once; never design code paths that replace the server at runtime."],"tags":["jmx","invalid-state","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}