Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit 3a846a3

Browse files
author
Tomas Knappek
committed
Fixes JERSEY-2891: ExceptionMapper not chosen correctly in case of multiple ExtendedExceptionMappers with same generic type
1 parent 0214b7d commit 3a846a3

File tree

2 files changed

+566
-24
lines changed

2 files changed

+566
-24
lines changed

core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,8 @@
4747
import java.util.Collection;
4848
import java.util.Comparator;
4949
import java.util.LinkedHashSet;
50-
import java.util.Map;
5150
import java.util.Set;
5251
import java.util.SortedSet;
53-
import java.util.TreeMap;
5452
import java.util.TreeSet;
5553
import java.util.logging.Level;
5654
import java.util.logging.Logger;
@@ -122,35 +120,29 @@ public <T extends Throwable> ExceptionMapper<T> find(final Class<T> type) {
122120

123121
@SuppressWarnings("unchecked")
124122
private <T extends Throwable> ExceptionMapper<T> find(final Class<T> type, final T exceptionInstance) {
125-
126-
final Map<Integer, ExceptionMapper<T>> orderedMappers = new TreeMap<Integer, ExceptionMapper<T>>();
127-
123+
ExceptionMapper<T> mapper = null;
124+
int minDistance = Integer.MAX_VALUE;
128125
for (final ExceptionMapperType mapperType : exceptionMapperTypes) {
129126
final int d = distance(type, mapperType.exceptionType);
130-
if (d >= 0) {
131-
orderedMappers.put(d, mapperType.mapper.getService());
132-
}
133-
}
134-
135-
if (orderedMappers.size() == 0) {
136-
return null;
137-
}
138-
139-
if (exceptionInstance != null) {
140-
for (final ExceptionMapper<T> mapper : orderedMappers.values()) {
141-
if (mapper instanceof ExtendedExceptionMapper) {
142-
final boolean mappable = ((ExtendedExceptionMapper<T>) mapper).isMappable(exceptionInstance);
143-
if (mappable) {
127+
if (d >= 0 && d <= minDistance) {
128+
final ExceptionMapper<T> candidateMapper = mapperType.mapper.getService();
129+
if (isMappable(exceptionInstance, candidateMapper)) {
130+
mapper = candidateMapper;
131+
minDistance = d;
132+
if (d == 0) {
133+
// slight optimization: if the distance is 0, it is already the best case, so we can exit
144134
return mapper;
145135
}
146-
} else {
147-
return mapper;
148136
}
149137
}
150-
return null;
151-
} else {
152-
return orderedMappers.values().iterator().next();
153138
}
139+
return mapper;
140+
}
141+
142+
private <T extends Throwable> boolean isMappable(T exceptionInstance, ExceptionMapper<T> mapper) {
143+
return exceptionInstance == null
144+
|| !(mapper instanceof ExtendedExceptionMapper)
145+
|| ((ExtendedExceptionMapper<T>) mapper).isMappable(exceptionInstance);
154146
}
155147

156148
/**

0 commit comments

Comments
 (0)