apache/hadoop · error · UnsupportedOperationException
Unbound
Error message
Unbound ${method} What it means
DynamicWrappedIO binds seven static methods of org.apache.hadoop.io.wrappedio.WrappedIO reflectively via DynMethods (bulkDelete_delete, bulkDelete_pageSize, fileSystem_openFile, pathCapabilities_hasPathCapability, streamCapabilities_hasCapability, byteBufferPositionedReadable_readFullyAvailable, byteBufferPositionedReadable_readFully). requireAllMethodsAvailable() throws UnsupportedOperationException("Unbound " + method) when any binding is null — meaning the WrappedIO class was found but does not contain that exact static method with the expected signature (or was not found at all, leaving every method unbound).
Solutions
- Align hadoop-common versions across the classpath: inspect with mvn dependency:tree or dump java.classpath and remove/upgrade the stray older hadoop-common jar.
- At startup check DynamicWrappedIO.loaded() and the per-API probes (bulkDelete_available(), etc.) instead of assuming all methods are bound.
- If you vendored a copy of DynamicWrappedIO, update the method-name constants and signatures to match the WrappedIO version actually on your classpath.
- Look for shaded/duplicate org.apache.hadoop classes (jar tf | grep 'wrappedio/WrappedIO') and keep exactly one version.
Example fix
// before
new DynamicWrappedIO().requireAllMethodsAvailable(); // UnsupportedOperationException: Unbound ... after hadoop-common downgrade
// after
DynamicWrappedIO dio = new DynamicWrappedIO();
if (!dio.loaded() || !dio.bulkDelete_available()) {
LOG.warn("WrappedIO incomplete on classpath; falling back to non-vectored path");
} else {
// safe to use the dynamic bindings
} Defensive patterns
Strategy: validation
Validate before calling
DynamicWrappedIO dio = new DynamicWrappedIO();
if (!dio.loaded()) {
throw new IllegalStateException("WrappedIO class missing from classpath");
}
if (!dio.bulkDelete_available()) {
LOG.warn("bulkDelete unbound: hadoop-common version mismatch");
} Try / catch
try {
dyn.requireAllMethodsAvailable();
} catch (UnsupportedOperationException e) {
// name the unbound method; audit classpath for duplicate/old hadoop-common jars
LOG.error("WrappedIO binding incomplete: {}", e.getMessage());
} Prevention
- Enforce a single hadoop-common version via dependencyManagement and check with dependency:tree in CI.
- Probe loaded() and per-API *_available() before first use, not requireAllMethodsAvailable() blindly.
- If vendoring DynamicWrappedIO, keep its method constants in lockstep with the WrappedIO version you target.
- Add a smoke test that constructs DynamicWrappedIO() in the assembled (shaded) jar, not just in the reactor.
When it happens
Trigger: Instantiating DynamicWrappedIO against a hadoop-common jar older or newer than the WrappedIO API this class expects (method renamed, added, or signature changed); the WrappedIO class absent from the classpath (loadClass returns null so all loadStaticMethod calls yield unbound methods); duplicate/shaded copies of hadoop-common where an older WrappedIO wins classloading; invoking requireAllMethodsAvailable() in tests after a version bump.
Common situations: Version drift between hadoop-common artifacts on one classpath; third-party stores copying DynamicWrappedIO into their codebase (the 'copy-and-paste adoption' the loaded flag mentions); dependency shading pinning an older hadoop-common; upgrading Hadoop in a project that vendors this adapter.
Related errors
- Cannot find method
- Cannot initialize the class
- Error creating plugin
- Failed to create Store Operations from configuration option…
- Unknown channel mode
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/1d32183ed8276525.
Report an issue: GitHub.
Appendix: source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/wrappedio/impl/DynamicWrappedIO.java:239
/**
* For testing: verify that all methods were found.
* @throws UnsupportedOperationException if the method was not found.
*/
void requireAllMethodsAvailable() throws UnsupportedOperationException {
final DynMethods.UnboundMethod[] methods = {
bulkDeleteDeleteMethod,
bulkDeletePageSizeMethod,
fileSystemOpenFileMethod,
pathCapabilitiesHasPathCapabilityMethod,
streamCapabilitiesHasCapabilityMethod,
byteBufferPositionedReadableReadFullyAvailableMethod,
byteBufferPositionedReadableReadFullyMethod,
};
for (DynMethods.UnboundMethod method : methods) {
LOG.info("Checking method {}", method);
if (!available(method)) {
throw new UnsupportedOperationException("Unbound " + method);
}
}
}
/**
* Are the bulk delete methods available?
* @return true if the methods were found.
*/
public boolean bulkDelete_available() {
return available(bulkDeleteDeleteMethod);
}
/**
* Get the maximum number of objects/files to delete in a single request.
* @param fileSystem filesystem
* @param path path to delete under.
* @return a number greater than or equal to zero.View on GitHub (pinned to 2add963021)