{"record":{"id":"87768c94671073a1","repo":"Tencent/matrix","slug":"not-allow-for-subordinate-processes","errorCode":null,"errorMessage":"NOT allow for subordinate processes","messagePattern":"NOT allow for subordinate processes","errorType":"exception","errorClass":"IllegalAccessException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/supervisor/ProcessSubordinate.kt","lineNumber":35,"sourceCode":"    fun addDyingListener(listener: (recentScene: String?, processName: String?, pid: Int?) -> Boolean)\n    fun removeDyingListener(listener: (recentScene: String?, processName: String?, pid: Int?) -> Boolean)\n    fun addDeathListener(listener: (recentScene: String?, processName: String?, pid: Int?, isLruKill: Boolean?) -> Unit)\n    fun removeDeathListener(listener: (recentScene: String?, processName: String?, pid: Int?, isLruKill: Boolean?) -> Unit)\n    fun getRecentScene(): String\n}\n\n/**\n * Created by Yves on 2021/12/30\n */\ninternal object ProcessSubordinate {\n\n    private val TAG by lazy { \"${ProcessSupervisor.tag}.Subordinate\" }\n\n    internal val manager by lazy {\n        if (ProcessSupervisor.isSupervisor) {\n            Manager()\n        } else {\n            throw IllegalAccessException(\"NOT allow for subordinate processes\")\n        }\n    }\n\n    internal class Manager {\n        private val subordinateProxies by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ConcurrentHashMap<ProcessToken, ISubordinateProxy>() }\n\n        private fun Map<ProcessToken, ISubordinateProxy>.forEachSafe(action: (Map.Entry<ProcessToken, ISubordinateProxy>) -> Unit) {\n            forEach { e ->\n                safeLet(unsafe = { action(e) }, failed = {\n                    MatrixLog.printErrStackTrace(TAG, it, \"${e.key.pid}${e.key.name}\")\n                    if (it is DeadObjectException) {\n                        MatrixLog.e(TAG, \"remote process of proxy is dead, remove proxy: ${e.key}\")\n                        subordinateProxies.remove(e.key)\n                    }\n                })\n            }\n        }\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/supervisor/ProcessSubordinate.kt#L17-L53","documentation":"ProcessSubordinate.manager is a lazy singleton exposing the subordinate management API. On a supervisor process the lazy initializer builds the Manager; on a subordinate process it throws IllegalAccessException(\"NOT allow for subordinate processes\"), because managing subordinate proxies is exclusively a supervisor capability.","triggerScenarios":"Accessing ProcessSubordinate.manager from a process where ProcessSupervisor.isSupervisor is false — e.g. a subordinate process touching the manager to enumerate or manipulate subordinate proxies.","commonSituations":"Shared code paths that touch ProcessSubordinate on both process types; debugging session where the app ran as a subordinate; misconfigured supervisor service enabling so the expected supervisor became a subordinate.","solutions":["Only access ProcessSubordinate.manager inside code guarded by ProcessSupervisor.isSupervisor.","Restructure shared logic so manager access lives in supervisor-only classes or modules.","Verify ProcessSupervisor.init was called with a configuration that makes this process the supervisor (service declaration, enable flags).","Catch IllegalAccessException around the manager access when process role is not statically known."],"exampleFix":"// before\nval manager = ProcessSubordinate.manager\n// after\nif (ProcessSupervisor.isSupervisor) {\n    val manager = ProcessSubordinate.manager\n}","handlingStrategy":"validation","validationCode":"if (!ProcessSupervisor.isSupervisor) {\n    MatrixLog.w(TAG, \"manager is supervisor-only\")\n    return\n}\nval manager = ProcessSubordinate.manager","typeGuard":"fun subordinateManagerOrNull(): ProcessSubordinate.Manager? =\n    if (ProcessSupervisor.isSupervisor) ProcessSubordinate.manager else null","tryCatchPattern":"val manager = try {\n    ProcessSubordinate.manager\n} catch (e: IllegalAccessException) {\n    MatrixLog.w(TAG, \"not a supervisor process\", e)\n    null\n}","preventionTips":["Access ProcessSubordinate.manager only from supervisor-only components.","Verify the supervisor service configuration so the intended process actually is the supervisor.","Use runCatching around role-dependent singletons when the process role is dynamic."],"tags":["android","process-supervisor","access-control","illegal-access"],"backgroundTag":"insufficient-permissions","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}