This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new aaf62b79ff7 CXF-7330: Require all type variable bounds to match when
selecting providers (#3575)
aaf62b79ff7 is described below
commit aaf62b79ff7e6bb7cf193ea94d8c7031a3aa5b81
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Wed Oct 14 13:31:14 2026 +0100
CXF-7330: Require all type variable bounds to match when selecting
providers (#3575)
---
.../apache/cxf/jaxrs/provider/ProviderFactory.java | 7 ++---
.../cxf/jaxrs/provider/ProviderFactoryTest.java | 31 +++++++++++++++++++++-
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
index 18f0a9e1098..e89b66777db 100644
---
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
+++
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
@@ -393,11 +393,12 @@ public abstract class ProviderFactory {
if (arg instanceof TypeVariable) {
TypeVariable<?> var = (TypeVariable<?>) arg;
Type[] bounds = var.getBounds();
- boolean isResolved = false;
+ // all the bounds must match, e.g. T extends Throwable
& SomeInterface
+ boolean isResolved = true;
for (Type bound : bounds) {
Class<?> cls = InjectionUtils.getRawType(bound);
- if (cls != null && (cls == Object.class ||
cls.isAssignableFrom(expectedType))) {
- isResolved = true;
+ if (cls == null || (cls != Object.class &&
!cls.isAssignableFrom(expectedType))) {
+ isResolved = false;
break;
}
}
diff --git
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
index da351ce764d..db993f2091d 100644
---
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
+++
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
@@ -831,6 +831,16 @@ public class ProviderFactoryTest {
assertNull(mapper2);
}
+ @Test
+ public void testExceptionMapperWithMultipleBounds() {
+ ServerProviderFactory pf = ServerProviderFactory.getInstance();
+ FaultInfoExceptionMapper<?> faultInfoMapper = new
FaultInfoExceptionMapper<>();
+ pf.registerUserProvider(faultInfoMapper);
+ assertSame(faultInfoMapper,
+ pf.createExceptionMapper(FaultInfoException.class, new
MessageImpl()));
+ assertNull(pf.createExceptionMapper(RuntimeException.class, new
MessageImpl()));
+ }
+
@Test
public void testRegisterCustomResolver() throws Exception {
ProviderFactory pf = ServerProviderFactory.getInstance();
@@ -1616,4 +1626,23 @@ public class ProviderFactoryTest {
}
}
-}
\ No newline at end of file
+ public interface FaultInfo {
+ String getFaultInfo();
+ }
+
+ public static class FaultInfoException extends RuntimeException implements
FaultInfo {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String getFaultInfo() {
+ return "fault";
+ }
+ }
+
+ public static class FaultInfoExceptionMapper<T extends Throwable &
FaultInfo> implements ExceptionMapper<T> {
+ @Override
+ public Response toResponse(T exception) {
+ return
Response.serverError().entity(exception.getFaultInfo()).build();
+ }
+ }
+}