{"record":{"id":"a4d73ee81f259012","repo":"alibaba/nacos","slug":"nacoslockservice-has-been-shut-down","errorCode":null,"errorMessage":"NacosLockService has been shut down","messagePattern":"NacosLockService has been shut down","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/com/alibaba/nacos/client/lock/NacosLockService.java","lineNumber":77,"sourceCode":"    private ScheduledExecutorService executorService;\n    \n    public NacosLockService(Properties properties) throws NacosException {\n        NacosClientProperties nacosClientProperties =\n            NacosClientProperties.PROTOTYPE.derive(properties);\n        this.serverListManager = new NamingServerListManager(properties);\n        serverListManager.start();\n        this.securityProxy = new SecurityProxy(serverListManager,\n            NamingHttpClientManager.getInstance().getNacosRestTemplate());\n        initSecurityProxy(nacosClientProperties);\n        this.lockGrpcClient =\n            new LockGrpcClient(nacosClientProperties, serverListManager, securityProxy);\n        this.watchdog = new NacosLockWatchdog();\n        this.clientId = UUID.randomUUID().toString();\n    }\n    \n    private void checkNotClosed() {\n        if (closed.get()) {\n            throw new IllegalStateException(\"NacosLockService has been shut down\");\n        }\n    }\n    \n    private void initSecurityProxy(NacosClientProperties properties) {\n        this.executorService = new ScheduledThreadPoolExecutor(1, r -> {\n            Thread t = new Thread(r);\n            t.setName(\"com.alibaba.nacos.client.lock.security\");\n            t.setDaemon(true);\n            return t;\n        });\n        final Properties nacosClientPropertiesView = properties.asProperties();\n        this.securityProxy.login(nacosClientPropertiesView);\n        this.executorService.scheduleWithFixedDelay(\n            () -> securityProxy.login(nacosClientPropertiesView), 0,\n            SECURITY_INFO_REFRESH_INTERVAL_MILLS, TimeUnit.MILLISECONDS);\n    }\n    \n    @Override","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/client/src/main/java/com/alibaba/nacos/client/lock/NacosLockService.java#L59-L95","documentation":"Thrown by NacosLockService.checkNotClosed() when any lock operation (lock, unLock, renew, remoteTryLock, remoteReleaseLock, getReentrantLock, getNonReentrantLock) is invoked after shutdown(). The service uses an AtomicBoolean 'closed' flag; shutdown() flips it to true via compareAndSet. After that, all public methods reject calls with IllegalStateException to prevent use of torn-down resources (gRPC client, watchdog, server list manager).","triggerScenarios":"Calling lock/unlock/renew after NacosLockService.shutdown(); holding a NacosLock reference obtained before shutdown and calling unlock() on it; a dependency-injection or lifecycle container shutting down the service while application code still issues lock operations.","commonSituations":"Application shutdown sequences where the NacosLockService is closed before outstanding lock operations finish; Spring/CDI @PreDestroy ordering issues; frameworks (test teardown, servlet context destroy) closing shared resources too early; using a cached/stale service reference after a reconnect that created a new service.","solutions":["Order shutdown so no lock operations occur after NacosLockService.shutdown(); release all locks and finish critical sections first.","Track service lifecycle in your own code and guard lock calls with an isOpen/isRunning check before invoking.","In DI containers, ensure NacosLockService is destroyed last; use @DependsOn or explicit destroy-order so consumers shut down before the service.","If the service was closed unexpectedly, create a new NacosLockService instance rather than reusing the shut-down one."],"exampleFix":"// before\nlockService.shutdown();\nlockService.lock(instance); // throws IllegalStateException\n\n// after\nlockService.shutdown();\n// ensure no further lock calls; if needed, create a fresh instance\nNacosLockService fresh = new NacosLockService(properties);","handlingStrategy":"validation","validationCode":"// Track your own lifecycle flag before calling lock operations\nif (!closed) { lockService.lock(instance); }","typeGuard":null,"tryCatchPattern":"try { lockService.lock(instance); } catch (IllegalStateException e) { if (e.getMessage().contains(\"shut down\")) { // service closed; create a new instance or stop } }","preventionTips":["Order DI/component shutdown so the NacosLockService is destroyed last.","Finish all lock operations before calling shutdown().","Do not cache a stale service reference across reconnects."],"tags":["lock","lifecycle","shutdown","illegal-state","resource-management"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}