junit-team/junit5 · error · ExtensionConfigurationException

LocaleProvider instance could not be constructed because of…

Error message

LocaleProvider instance could not be constructed because of an exception

What it means

ExtensionConfigurationException from DefaultLocaleExtension.getFromProvider, thrown when the configured LocaleProvider class cannot be instantiated. The class is loaded and constructed via ReflectionSupport.newInstance; any exception (NoSuchMethodException, SecurityException, InvocationTargetException from a failing constructor, IllegalAccessException) is wrapped and rethrown.

Solutions

  1. Give the LocaleProvider class a public no-argument constructor.
  2. Make the class public (and top-level or public static nested) so reflection can reach it.
  3. Ensure the provider constructor does not throw — move risky initialization into get().
  4. Inspect the wrapped cause exception for the precise reflection failure.

Example fix

// before
class MyProvider implements LocaleProvider {
    public MyProvider(String cfg) { /* ... */ }
    public Locale get() { return Locale.US; }
}
// after
public class MyProvider implements LocaleProvider {
    public MyProvider() {}
    public Locale get() { return Locale.US; }
}
Defensive patterns

Strategy: validation

Validate before calling

Class<? extends LocaleProvider> c = annotation.localeProvider();
int mods = c.getModifiers();
if (Modifier.isAbstract(mods) || !Modifier.isPublic(mods)) { /* fix visibility */ }
if (Arrays.stream(c.getConstructors()).noneMatch(con -> con.getParameterCount() == 0)) { /* add no-arg ctor */ }

Type guard

static boolean instantiableLocaleProvider(Class<?> c) {
    int m = c.getModifiers();
    return Modifier.isPublic(m) && !Modifier.isAbstract(m)
        && Arrays.stream(c.getConstructors()).anyMatch(con -> con.getParameterCount() == 0);
}

Prevention

When it happens

Trigger: Specifying @DefaultLocale(localeProvider = MyProvider.class) where MyProvider has no public no-arg constructor, is abstract, is non-public/inaccessible, or its constructor throws.

Common situations: Provider class with only a parameterized constructor; a nested non-static provider class; provider constructor doing work that fails (reading a file, env lookup); provider not on the classpath module path in a modular test run.

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/eac84f3c5050f19f. Report an issue: GitHub.

Appendix: source

Thrown at junit-jupiter-api/src/main/java/org/junit/jupiter/api/util/DefaultLocaleExtension.java:112

		}
		else {
			throw new ExtensionConfigurationException(
				"@DefaultLocale not configured correctly. When not using a language tag, specify either"
						+ " language, or language and country, or language and country and variant.");
		}
	}

	private static Locale getFromProvider(DefaultLocale annotation) {
		if (!annotation.country().isEmpty() || !annotation.variant().isEmpty())
			throw new ExtensionConfigurationException(
				"@DefaultLocale can only be used with a provider if value, language, country and variant are not set.");
		var providerClass = annotation.localeProvider();
		LocaleProvider provider;
		try {
			provider = ReflectionSupport.newInstance(providerClass);
		}
		catch (Exception exception) {
			throw new ExtensionConfigurationException(
				"LocaleProvider instance could not be constructed because of an exception", exception);
		}
		return invoke(provider);
	}

	@SuppressWarnings("ConstantValue")
	private static Locale invoke(LocaleProvider provider) {
		var locale = provider.get();
		if (locale == null) {
			throw new ExtensionConfigurationException("LocaleProvider instance returned with null");
		}
		return locale;
	}

	@Override
	public void afterEach(ExtensionContext context) {
		load(context, DEFAULT_KEY).ifPresent(Locale::setDefault);
	}

View on GitHub (pinned to f070c699a0)