hibernate/hibernate-orm · error · HibernateException

The ClassLoaderService cannot be reused (this instance was s

Error message

The ClassLoaderService cannot be reused (this instance was stopped already)

What it means

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().

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java:251

		catch (ClassNotFoundException e) {
			BOOT_LOGGER.packageNotFound( packageName );
			return null;
		}
		catch (LinkageError e) {
			BOOT_LOGGER.linkageError( packageName, e );
			return null;
		}
	}

	@Override
	public <T> T workWithClassLoader(@Nonnull Work<T> work) {
		return work.doWork( getAggregatedClassLoader() );
	}

	private AggregatedClassLoader getAggregatedClassLoader() {
		final AggregatedClassLoader aggregated = this.aggregatedClassLoader;
		if ( aggregated == null ) {
			throw new HibernateException( "The ClassLoaderService cannot be reused (this instance was stopped already)" );
		}
		return aggregated;
	}

	private String stripClasspathScheme(String name) {
		if ( name == null ) {
			return null;
		}

		if ( name.startsWith( CLASS_PATH_SCHEME ) ) {
			return name.substring( CLASS_PATH_SCHEME.length() );
		}

		return name;
	}

	@Override
	public void stop() {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Build a new SessionFactory/EntityManagerFactory from a fresh registry instead of reusing the stopped one
  2. Audit for components caching ClassLoaderService or the ServiceRegistry in static fields and clear them on close
  3. Close in the correct order exactly once: SessionFactory, then StandardServiceRegistry, then let the BootstrapServiceRegistry auto-close
  4. If a framework restarts registries, re-obtain services from the new registry after restart rather than holding old references
Defensive patterns

Strategy: validation

Validate before calling

// Check liveness of the owning registry before using its services
if (!serviceRegistry.isActive()) {
    throw new IllegalStateException("Registry already stopped - rebuild the SessionFactory");
}
ClassLoaderService cls = serviceRegistry.getService(ClassLoaderService.class);

Try / catch

try {
    Class<?> type = classLoaderService.classForName(name);
} catch (HibernateException e) {
    if (e.getMessage().contains("cannot be reused")) {
        // the owning registry was stopped: drop cached references and rebuild
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/c816f6d261da38ac. Report an issue: GitHub.