{"record":{"id":"6ffebef05451ada1","repo":"apache/incubator-seata","slug":"servermessagesender-must-not-be-null","errorCode":null,"errorMessage":"serverMessageSender must not be null","messagePattern":"serverMessageSender must not be null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/seata/core/rpc/DefaultServerMessageListenerImpl.java","lineNumber":224,"sourceCode":"        ExecutorService mergeSendExecutorService = ThreadPoolExecutorFactory.newThreadPoolExecutor(\n                THREAD_PREFIX,\n                MAX_LOG_SEND_THREAD,\n                MAX_LOG_SEND_THREAD,\n                KEEP_ALIVE_TIME,\n                TimeUnit.MILLISECONDS,\n                new LinkedBlockingQueue<Runnable>(),\n                true);\n        mergeSendExecutorService.submit(new BatchLogRunnable());\n    }\n\n    /**\n     * Gets server message sender.\n     *\n     * @return the server message sender\n     */\n    public RemotingServer getServerMessageSender() {\n        if (remotingServer == null) {\n            throw new IllegalArgumentException(\"serverMessageSender must not be null\");\n        }\n        return remotingServer;\n    }\n\n    /**\n     * Sets server message sender.\n     *\n     * @param remotingServer the remoting server\n     */\n    public void setServerMessageSender(RemotingServer remotingServer) {\n        this.remotingServer = remotingServer;\n    }\n\n    /**\n     * The type Batch log runnable.\n     */\n    static class BatchLogRunnable implements Runnable {\n","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/core/src/main/java/org/apache/seata/core/rpc/DefaultServerMessageListenerImpl.java#L206-L242","documentation":"DefaultServerMessageListenerImpl.getServerMessageSender() throws if remotingServer was never injected via setServerMessageSender. The listener needs the RemotingServer to push asynchronous responses/requests back to clients; using it before wiring is a bean-lifecycle or configuration error, not a runtime race.","triggerScenarios":"Manually constructing DefaultServerMessageListenerImpl (e.g. in tests or custom bootstrap) and calling send-back APIs without calling setServerMessageSender; or a Spring/@Bean configuration where the listener bean is created/resolved before the remoting server bean is wired into it.","commonSituations":"Custom server-side bootstrap replacing the default Seata server assembly; unit tests instantiating the listener directly; @Autowired ordering issues where an eager init consumes the listener pre-wiring.","solutions":["Ensure setServerMessageSender(remotingServer) is called during assembly before any message handling — in Spring, wire it as a required @Autowired setter or constructor arg.","In tests, stub a RemotingServer and inject it in @BeforeEach.","Prefer reusing the framework's server bootstrap rather than reassembling beans by hand."],"exampleFix":"// before\nDefaultServerMessageListenerImpl l = new DefaultServerMessageListenerImpl();\nl.getServerMessageSender().sendResponse(msg);\n// after\nRemotingServer stub = mock(RemotingServer.class);\nl.setServerMessageSender(stub);\nl.getServerMessageSender().sendResponse(msg);","handlingStrategy":"validation","validationCode":"if (listener.getServerMessageSender() == null /* would throw */) {\n    throw new IllegalStateException(\"wire setServerMessageSender before use\");\n}\n// simpler: inject via constructor/Spring so it cannot be missing\nDefaultServerMessageListenerImpl l = new DefaultServerMessageListenerImpl();\nl.setServerMessageSender(remotingServer); // required assembly step","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"must not be null\")) { throw new IllegalStateException(\"listener used before wiring\", e); }\n}","preventionTips":["Prefer constructor injection for mandatory collaborators","Assert wiring in @PostValidate/@AfterPropertiesSet startup hooks"],"tags":["wiring","spring","lifecycle","null-check"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}