apache/shenyu · error · UnsupportedOperationException
@ShenyuClient please use it on the interface.
Error message
@ShenyuClient please use it on the interface.
What it means
ShenyuClientProxyFactory.createProxy() builds a JDK dynamic proxy, which can only implement interfaces. It checks apiClass.isInterface() first and throws UnsupportedOperationException when a concrete class is passed, reminding users that @ShenyuClient must be placed on an interface.
Solutions
- Extract the client methods into an interface annotated with @ShenyuClient and have the class implement it.
- Pass the interface Class to ShenyuClientFactoryBean/createProxy, not the implementation class.
- If using generics, ensure the resolved type parameter is the interface (check with apiClass.isInterface() in your own code first).
Example fix
// before
@ShenyuClient(name = "order")
public class OrderClient { @Get("/order") OrderDTO get(); }
// after
@ShenyuClient(name = "order")
public interface OrderClient { @Get("/order") OrderDTO get(); } Defensive patterns
Strategy: validation
Validate before calling
if (!apiClass.isInterface()) {
throw new IllegalArgumentException("@ShenyuClient target must be an interface: " + apiClass.getName());
} Prevention
- Define clients only as interfaces annotated with @ShenyuClient.
- Pass interface Class tokens to ShenyuClientFactoryBean, never implementations.
- Check generic type resolution returns the interface when building clients reflectively.
When it happens
Trigger: Passing a concrete class to createProxy / the factory bean — e.g. annotating a class with @ShenyuClient, or programmatically registering ShenyuClientFactoryBean with a class type instead of an interface.
Common situations: Coming from other HTTP client frameworks that allow classes; refactoring merged interface into a class; generic type resolution returning the implementation class instead of the interface; misconfigured Class<T> parameter.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- shenyu.jwt.secretKey is not configured. In a multi-instance…
- clientConfig must config " + getClientName() + " properties
- shenyu register into ShenyuDiscoveryService
- grpc client must config the contextPath, ipAndPort
- tars client must config the contextPath, ipAndPort
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/2429aa068bf8e1ef.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/proxy/ShenyuClientProxyFactory.java:48
*/
public final class ShenyuClientProxyFactory {
/**
* PROXY_CACHE.
*/
private static final ConcurrentMap<Class<?>, Object> PROXY_CACHE = new ConcurrentHashMap<>();
/**
* createProxy.
*
* @param apiClass apiClass
* @param applicationContext applicationContext
* @param shenyuClientFactoryBean shenyuClientFactoryBean
* @return {@link Object}
*/
public static Object createProxy(final Class<?> apiClass, final ApplicationContext applicationContext, final ShenyuClientFactoryBean shenyuClientFactoryBean) {
if (!apiClass.isInterface()) {
throw new UnsupportedOperationException("@ShenyuClient please use it on the interface. " + apiClass.getName());
}
if (PROXY_CACHE.containsKey(apiClass)) {
return PROXY_CACHE.get(apiClass);
}
synchronized (apiClass) {
Object proxy = Proxy.newProxyInstance(apiClass.getClassLoader(),
new Class<?>[]{apiClass},
new ShenyuClientInvocationHandler(apiClass, applicationContext, shenyuClientFactoryBean));
PROXY_CACHE.put(apiClass, proxy);
}
return PROXY_CACHE.get(apiClass);
}
}
View on GitHub (pinned to 567142e072)