{"record":{"id":"ba5fbcdc38bd8e99","repo":"eclipse-vertx/vert.x","slug":"resource-manager-closed","errorCode":null,"errorMessage":"Resource manager closed","messagePattern":"Resource manager closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/internal/resource/ResourceManager.java","lineNumber":112,"sourceCode":"   *\n   * @param key the resource key\n   * @return the future resolved with the resource\n   */\n  public <T> Future<T> withResourceAsync(K key, Function<K, R> provider, BiFunction<R, Boolean, Future<T>> function) {\n    return withResource(key, provider, Function.identity(), (res, created) -> {\n      if (res.before()) {\n        return function.apply(res, created).andThen(ar -> res.after());\n      }\n      return null;\n    });\n  }\n\n  private void checkStatus() {\n    int st = status.get();\n    if (st == 1) {\n      throw new IllegalStateException(\"Resource manager shutdown\");\n    } else if (st == 2) {\n      throw new IllegalStateException(\"Resource manager closed\");\n    }\n  }\n\n  /**\n   * Shutdown the resource manager: any new request will be rejected.\n   */\n  public void shutdown() {\n    if (status.compareAndSet(0, 1)) {\n      for (ManagedResource resource : resources.values()) {\n        resource.shutdown();\n      }\n      status.set(2);\n    }\n  }\n\n  /**\n   * Close the resource manager, all resource are closed forcibly.\n   */","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/internal/resource/ResourceManager.java#L94-L130","documentation":"ResourceManager.checkStatus() throws this IllegalStateException when the manager status is 2, i.e. close() has fully completed. After close, all resources have been released and no new withResource() requests are accepted. It differs from 'shutdown' (status 1), which rejects new work but is a softer phase.","triggerScenarios":"Calling withResource (or any resource-acquiring API) after ResourceManager.close() finished — typically using a Vertx instance, client, or connection provider after its close() completed, or a stale reference to a manager captured before close.","commonSituations":"Reusing a closed Vertx/client from a static or cached field; scheduled/periodic tasks firing after the owning instance was closed; double-close bugs where a second component still holds the old manager.","solutions":["Stop all consumers before calling close(); cancel schedulers and complete in-flight work first","Create a fresh Vertx/client/manager instance instead of using the closed one","Clear cached references to closed managers so stale code paths cannot reach them","Catch IllegalStateException and treat it as a terminal lifecycle signal — reinitialize or fail the caller deliberately"],"exampleFix":"// before\nprivate static final Vertx VERTX = Vertx.vertx(); // closed elsewhere, reused later -> Resource manager closed\n// after\nprivate volatile Vertx vertx;\nVertx v = vertx;\nif (v == null) { v = Vertx.vertx(); vertx = v; }","handlingStrategy":"try-catch","validationCode":"// keep a closed flag around the manager holder\nif (managerClosed.get()) {\n  return Future.failedFuture(new IllegalStateException(\"manager already closed\"));\n}\nreturn manager.withResource(key, supplier);","typeGuard":"boolean usable(ResourceManager m) { return m != null && !m.isClosed(); } // track close via your own flag or wrapper","tryCatchPattern":"try {\n  return manager.withResource(key, supplier);\n} catch (IllegalStateException e) {\n  if (\"Resource manager closed\".equals(e.getMessage())) {\n    manager = recreate(); // or fail terminally — never retry on the closed instance\n    return manager.withResource(key, supplier);\n  }\n  throw e;\n}","preventionTips":["Clear cached/static references to a manager as soon as close() completes","Close the owning Vertx/client only after all consumers are stopped","Treat this error as terminal: recreate the instance instead of retrying on the closed one","Use lifecycle frameworks (DI close hooks) to enforce close ordering across components"],"tags":["lifecycle","closed","resource-manager","illegal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}