{"record":{"id":"c816f6d261da38ac","repo":"hibernate/hibernate-orm","slug":"the-classloaderservice-cannot-be-reused-this-inst","errorCode":null,"errorMessage":"The ClassLoaderService cannot be reused (this instance was stopped already)","messagePattern":"The ClassLoaderService cannot be reused \\(this instance was stopped already\\)","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java","lineNumber":251,"sourceCode":"\t\tcatch (ClassNotFoundException e) {\n\t\t\tBOOT_LOGGER.packageNotFound( packageName );\n\t\t\treturn null;\n\t\t}\n\t\tcatch (LinkageError e) {\n\t\t\tBOOT_LOGGER.linkageError( packageName, e );\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t@Override\n\tpublic <T> T workWithClassLoader(@Nonnull Work<T> work) {\n\t\treturn work.doWork( getAggregatedClassLoader() );\n\t}\n\n\tprivate AggregatedClassLoader getAggregatedClassLoader() {\n\t\tfinal AggregatedClassLoader aggregated = this.aggregatedClassLoader;\n\t\tif ( aggregated == null ) {\n\t\t\tthrow new HibernateException( \"The ClassLoaderService cannot be reused (this instance was stopped already)\" );\n\t\t}\n\t\treturn aggregated;\n\t}\n\n\tprivate String stripClasspathScheme(String name) {\n\t\tif ( name == null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( name.startsWith( CLASS_PATH_SCHEME ) ) {\n\t\t\treturn name.substring( CLASS_PATH_SCHEME.length() );\n\t\t}\n\n\t\treturn name;\n\t}\n\n\t@Override\n\tpublic void stop() {","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java#L233-L269","documentation":"ClassLoaderServiceImpl.stop() releases the aggregated class loader; getAggregatedClassLoader() then throws this HibernateException on every subsequent use (classForName, locateResource, workWithClassLoader). Seeing it means some component still holds and uses a ClassLoaderService after the registry that owns it was destroyed - the service is deliberately not reusable after stop().","triggerScenarios":"Calling classForName/locateResource/workWithClassLoader on a ClassLoaderService obtained from a registry that was already stopped - e.g., after StandardServiceRegistry/BootstrapServiceRegistry destroy, during framework dev-mode restarts, or in shutdown hooks that still touch Hibernate.","commonSituations":"Application redeploys keeping a stale static SessionFactory/EntityManagerFactory; test suites sharing a registry across test contexts and closing it early; framework restarts (Spring dev tools, Quarkus dev mode) while user code caches Hibernate services in static fields.","solutions":["Build a new SessionFactory/EntityManagerFactory from a fresh registry instead of reusing the stopped one","Audit for components caching ClassLoaderService or the ServiceRegistry in static fields and clear them on close","Close in the correct order exactly once: SessionFactory, then StandardServiceRegistry, then let the BootstrapServiceRegistry auto-close","If a framework restarts registries, re-obtain services from the new registry after restart rather than holding old references"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check liveness of the owning registry before using its services\nif (!serviceRegistry.isActive()) {\n    throw new IllegalStateException(\"Registry already stopped - rebuild the SessionFactory\");\n}\nClassLoaderService cls = serviceRegistry.getService(ClassLoaderService.class);","typeGuard":null,"tryCatchPattern":"try {\n    Class<?> type = classLoaderService.classForName(name);\n} catch (HibernateException e) {\n    if (e.getMessage().contains(\"cannot be reused\")) {\n        // the owning registry was stopped: drop cached references and rebuild\n    }\n    throw e;\n}","preventionTips":["Never cache ClassLoaderService or ServiceRegistry in static fields across restarts","Own the full close chain (EMF -> registry) in one place, closing exactly once","On framework dev-mode restarts, re-obtain services from the new registry"],"tags":["hibernate","lifecycle","service-registry","classloading","shutdown"],"backgroundTag":"resource-used-after-close","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}