hibernate/hibernate-orm · error · HibernateException

Unable to instantiate Scanner `%s`

Error message

Unable to instantiate Scanner `%s`

What it means

Thrown by PersistenceConfigurationDescriptor.determineScannerFromSetting() as a HibernateException when the class configured via the hibernate.archive.scanner setting (Class-object form) cannot be instantiated with getDeclaredConstructor().newInstance(). The Scanner is what actually walks archives to locate mapping files and classes, and its configured implementation must be constructible with a no-arg constructor.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/jpa/boot/spi/PersistenceConfigurationDescriptor.java:361

	private static Scanner determineScannerFromSetting(
			@Nonnull ConfigurationService configurationService,
			@Nonnull ClassLoaderService classLoaderService) {
		var setting = configurationService.getSettings().get( PersistenceSettings.SCANNER );
		if ( setting == null ) {
			return null;
		}

		// might be any of the 3 standard forms
		if ( setting instanceof Scanner instance ) {
			return instance;
		}
		else if ( setting instanceof Class<?> implClass ) {
			try {
				return (Scanner) implClass.getDeclaredConstructor().newInstance();
			}
			catch (Exception e) {
				throw new HibernateException(
						String.format( Locale.ROOT,
								"Unable to instantiate Scanner `%s`",
								implClass.getName()
						),
						e
				);
			}
		}
		else {
			var implClassName = setting.toString();
			var implClass = classLoaderService.classForName( implClassName );
			try {
				return (Scanner) implClass.getDeclaredConstructor().newInstance();
			}
			catch (Exception e) {
				throw new HibernateException(
						String.format( Locale.ROOT,
								"Unable to instantiate Scanner `%s`",

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add a public no-arg constructor to the Scanner implementation.
  2. Recompile the custom Scanner against the current Hibernate version so it implements the current org.hibernate.jpa.boot.spi.Scanner interface.
  3. Prefer configuring a ScanningProvider (hibernate.archive.scanning) instead of a raw Scanner in modern Hibernate.
  4. Inspect the cause for constructor-thrown failures and fix them.

Example fix

// before
public class ModuleScanner implements Scanner {
    public ModuleScanner(ModuleClassLoader cl) { ... } // no no-arg ctor
}
props.put("hibernate.archive.scanner", ModuleScanner.class);

// after
public class ModuleScanner implements Scanner {
    public ModuleScanner() { }
    void setClassLoader(ModuleClassLoader cl) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = (Class<?>) settings.get("hibernate.archive.scanner");
if (c != null) {
    if (!Scanner.class.isAssignableFrom(c)) throw new IllegalStateException(c + " does not implement current Scanner SPI");
    c.getDeclaredConstructor().newInstance();
}

Prevention

When it happens

Trigger: Setting hibernate.archive.scanner to a Class that has no accessible no-arg constructor, is abstract, or whose constructor throws, during EntityManagerFactory bootstrap when the archive scanner is determined.

Common situations: Plugging in a custom Scanner (e.g. to integrate with Quarkus/JBoss Modules scanning) that was written for an older Hibernate SPI or requires constructor arguments; migration to Hibernate 7 where the Scanner SPI moved to org.hibernate.jpa.boot.spi and old implementations no longer fit.

Related errors


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