flowable/flowable-engine · error · ELException

TypeConverter ${clazz} could not be instantiated

Error message

TypeConverter ${clazz} could not be instantiated

What it means

createTypeConverter() instantiates the TypeConverter implementation named by the PROP_TYPE_CONVERTER property via reflection (clazz.newInstance()). Any failure — no public no-arg constructor, abstract class, wrong type, or constructor exception — is wrapped as ELException 'TypeConverter X could not be instantiated'.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/ExpressionFactoryImpl.java:372

		return new TreeStore(builder, cache);
	}

	/**
	 * Create the factory's type converter. This implementation takes the
	 * <code>de.odysseus.el.misc.TypeConverter</code> property as the name of a class implementing
	 * the <code>de.odysseus.el.misc.TypeConverter</code> interface. If the property is not set, the
	 * default converter (<code>TypeConverter.DEFAULT</code>) is used.
	 */
	protected TypeConverter createTypeConverter(Properties properties) {
		Class<?> clazz = load(TypeConverter.class, properties);
		if (clazz == null) {
			return TypeConverter.DEFAULT;
		}
		try {
			return TypeConverter.class.cast(clazz.newInstance());
		} catch (Exception e) {
			throw new ELException("TypeConverter " + clazz + " could not be instantiated", e);
		}
	}

	/**
	 * Create the factory's builder. This implementation takes the
	 * <code>de.odysseus.el.tree.TreeBuilder</code> property as a name of a class implementing the
	 * <code>de.odysseus.el.tree.TreeBuilder</code> interface. If the property is not set, a plain
	 * <code>de.odysseus.el.tree.impl.Builder</code> is used. If the configured class is a subclass
	 * of <code>de.odysseus.el.tree.impl.Builder</code> and which provides a constructor taking an
	 * array of <code>Builder.Feature</code>, this constructor will be invoked. Otherwise, the
	 * default constructor will be used.
	 */
	protected TreeBuilder createTreeBuilder(Properties properties, Feature... features) {
		Class<?> clazz = load(TreeBuilder.class, properties);
		if (clazz == null) {
			return createDefaultTreeBuilder(features);
		}
		try {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Give the configured TypeConverter implementation a public no-argument constructor
  2. Verify the class extends/implements TypeConverter (so the cast succeeds)
  3. Confirm the class is concrete (not abstract/interface) and its constructor does not throw
  4. Remove the property to use TypeConverter.DEFAULT

Example fix

// before
public class MyConverter extends TypeConverterImpl {
    public MyConverter(String locale) { ... }
}

// after
public class MyConverter extends TypeConverterImpl {
    public MyConverter() { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName("com.acme.MyConverter");
if (!org.flowable.common.engine.impl.de.odysseus.el.TypeConverter.class.isAssignableFrom(c)
    || java.lang.reflect.Modifier.isAbstract(c.getModifiers())
    || c.getConstructors().length == 0 || java.util.Arrays.stream(c.getConstructors()).noneMatch(k -> k.getParameterCount() == 0)) {
    throw new IllegalStateException("TypeConverter must be concrete with a public no-arg constructor");
}

Try / catch

try {
    ExpressionFactory factory = new ExpressionFactoryImpl(props);
} catch (ELException e) {
    if (e.getMessage().contains("TypeConverter") && e.getMessage().contains("could not be instantiated")) {
        log.error("Check constructor/TypeConverter contract of configured class", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: ExpressionFactoryImpl construction with a TypeConverter property naming a class that lacks a public no-arg constructor, is abstract/interface, throws in its constructor, or does not extend TypeConverter (then ClassCastException in cast).

Common situations: Pointing the property at a custom converter with only parameterized constructors; typo causing the wrong class to be named; converter class present but initializing state in constructor that fails (e.g. missing Spring context).

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/adb5e9d503a1d3a9. Report an issue: GitHub.