testcontainers/testcontainers-java · error · IllegalArgumentException
The provided class does not implement…
Error message
The provided class does not implement 'com.hivemq.extension.sdk.api.ExtensionMain'
What it means
Builder.mainClass(Class) checks at runtime that the supplied class is assignable to com.hivemq.extension.sdk.api.ExtensionMain by loading the interface via Class.forName. If the provided class does not implement it, an IllegalArgumentException is thrown, because HiveMQ would fail to start the extension otherwise.
Solutions
- Make the passed class implement com.hivemq.extension.sdk.api.ExtensionMain (implement void action(ExtensionContext))
- Verify you are passing the extension entry-point class, not a helper/test class
- Add a compile-time generic bound or check the class hierarchy before calling mainClass
Example fix
// before builder.mainClass(SomeHelper.class); // does not implement ExtensionMain // after builder.mainClass(MyExtensionMain.class); // class MyExtensionMain implements ExtensionMain
Defensive patterns
Strategy: validation
Validate before calling
if (!com.hivemq.extension.sdk.api.ExtensionMain.class.isAssignableFrom(clazz)) throw new IllegalArgumentException(clazz + " must implement ExtensionMain");
Type guard
static boolean isExtensionMain(Class<?> c) { return com.hivemq.extension.sdk.api.ExtensionMain.class.isAssignableFrom(c); } Try / catch
try { builder.mainClass(clazz); } catch (IllegalArgumentException e) { /* log wrong class and fall back to correct ExtensionMain impl */ } Prevention
- Type the builder call with the concrete ExtensionMain implementation class
- Avoid passing Class<?> from reflection/config without an assignability check
When it happens
Trigger: Passing a Class<?> to mainClass(...) that does not implement ExtensionMain, e.g. a plain listener, helper, or wrong class picked up via reflection.
Common situations: Refactorings that renamed/moved the extension main class and an unrelated class got passed; dynamically resolving classes by name from config and grabbing the wrong one; generic test utility accepting arbitrary classes.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Could not create DISABLED file
- Could not parse extension id from
- Extension disabling timed out after
- Extension enabling timed out after
- extension id must not be null or empty
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/a0bfd944169d6be6.
Report an issue: GitHub.
Appendix: source
Thrown at modules/hivemq/src/main/java/org/testcontainers/hivemq/HiveMQExtension.java:305
public @NotNull Builder disabledOnStartup(final boolean disabledOnStartup) {
this.disabledOnStartup = disabledOnStartup;
return this;
}
/**
* The main class of the {@link HiveMQExtension}.
* This class MUST implement com.hivemq.extension.sdk.api.ExtensionMain.
*
* @param mainClass the main class
* @return the {@link Builder}
* @throws IllegalArgumentException if the provides class does not implement com.hivemq.extension.sdk.api.ExtensionMain}
* @throws IllegalStateException if com.hivemq.extension.sdk.api.ExtensionMain is not found in the classpath
*/
public @NotNull Builder mainClass(final @NotNull Class<?> mainClass) {
try {
final Class<?> extensionMain = Class.forName(EXTENSION_MAIN_CLASS_NAME);
if (!extensionMain.isAssignableFrom(mainClass)) {
throw new IllegalArgumentException(
"The provided class does not implement '" + EXTENSION_MAIN_CLASS_NAME + "'"
);
}
this.mainClass = mainClass;
return this;
} catch (final ClassNotFoundException e) {
throw new IllegalStateException(
"The class '" + EXTENSION_MAIN_CLASS_NAME + "' was not found in the classpath."
);
}
}
/**
* Adds an additional class to the .jar file of the {@link HiveMQExtension}.
*
* @param clazz the additional class
* @return the {@link Builder}
*/View on GitHub (pinned to 8e549514e3)