junit-team/junit5 · error · UnsupportedOperationException

Invoke convert(String, Class<?>, ClassLoader) instead

Error message

Invoke convert(String, Class<?>, ClassLoader) instead

What it means

StringToClassConverter's 2-arg convert(String, Class<?>) throws UnsupportedOperationException because resolving a Class requires a ClassLoader; callers must use the 3-arg convert(String, Class<?>, ClassLoader). ConversionSupport always invokes the 3-arg overload, so this only surfaces when the converter is used directly/programmatically.

Source

Thrown at junit-platform-commons/src/main/java/org/junit/platform/commons/support/conversion/StringToClassConverter.java:24

 * accompanies this distribution and is available at
 *
 * https://www.eclipse.org/legal/epl-v20.html
 */

package org.junit.platform.commons.support.conversion;

import org.junit.platform.commons.support.ReflectionSupport;

class StringToClassConverter implements StringToObjectConverter {

	@Override
	public boolean canConvertTo(Class<?> targetType) {
		return targetType == Class.class;
	}

	@Override
	public Object convert(String source, Class<?> targetType) throws Exception {
		throw new UnsupportedOperationException("Invoke convert(String, Class<?>, ClassLoader) instead");
	}

	@Override
	public Class<?> convert(String className, Class<?> targetType, ClassLoader classLoader) throws Exception {
		// @formatter:off
		return ReflectionSupport.tryToLoadClass(className, classLoader)
				.getNonNullOrThrow(cause -> new ConversionException(
						"Failed to convert String \"" + className + "\" to type java.lang.Class", cause));
		// @formatter:on
	}

}

View on GitHub (pinned to 956246301e)

Solutions

  1. Route through ConversionSupport.convert(source, Class.class, classLoader), which calls the 3-arg overload.
  2. If calling the converter directly, use the 3-arg convert(String, Class<?>, ClassLoader) overload and pass an explicit ClassLoader (or null for the default).
  3. Avoid relying on internal converter classes; prefer the public ConversionSupport facade.

Example fix

// before
converter.convert("java.lang.String", Class.class);

// after
converter.convert("java.lang.String", Class.class, classLoader);
// or simply:
ConversionSupport.convert("java.lang.String", Class.class, classLoader);
Defensive patterns

Strategy: validation

Validate before calling

// Always go through the 3-arg (ClassLoader-aware) entry point.
String name = "java.lang.String";
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> loaded = ConversionSupport.convert(name, Class.class, cl);

Try / catch

try {
    converter.convert(name, Class.class);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().contains("Invoke convert(String, Class<?>, ClassLoader)")) {
        // call the 3-arg overload with an explicit ClassLoader instead
    } else throw e;
}

Prevention

When it happens

Trigger: Calling `new StringToClassConverter().convert(name, Class.class)` directly, or invoking the StringToObjectConverter 2-arg interface method on this converter via reflection or a generic pipeline that does not pass a ClassLoader.

Common situations: Custom conversion code that reuses JUnit's internal converters directly; reflection dispatch that picks the 2-arg method.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/bb79997430f65d37.json. Report an issue: GitHub.