|
17 | 17 |
|
18 | 18 | import com.datastax.driver.core.exceptions.DriverInternalError; |
19 | 19 | import com.google.common.base.Function; |
20 | | -import com.google.common.collect.BiMap; |
21 | | -import com.google.common.collect.Maps; |
22 | 20 | import com.google.common.net.HostAndPort; |
23 | 21 | import com.google.common.reflect.TypeToken; |
24 | 22 | import com.google.common.util.concurrent.AsyncFunction; |
25 | 23 | import com.google.common.util.concurrent.FutureCallback; |
26 | 24 | import com.google.common.util.concurrent.Futures; |
27 | 25 | import com.google.common.util.concurrent.ListenableFuture; |
28 | 26 | import com.google.common.util.concurrent.MoreExecutors; |
29 | | -import java.lang.reflect.ParameterizedType; |
30 | | -import java.lang.reflect.Type; |
31 | | -import java.util.Map; |
32 | 27 | import java.util.concurrent.Executor; |
33 | 28 | import org.slf4j.Logger; |
34 | 29 | import org.slf4j.LoggerFactory; |
35 | 30 |
|
36 | 31 | /** |
37 | 32 | * A compatibility layer to support a wide range of Guava versions. |
38 | 33 | * |
39 | | - * <p>The driver is compatible with Guava 16.0.1 or higher, but Guava 20 introduced incompatible |
40 | | - * breaking changes in its API, that could in turn be breaking for legacy driver clients if we |
41 | | - * simply upgraded our dependency. We don't want to increment our major version "just" for Guava (we |
42 | | - * have other changes planned). |
| 34 | + * <p>The driver is compatible with Guava 19.0 or higher. |
43 | 35 | * |
44 | | - * <p>Therefore we depend on Guava 19, which has both the deprecated and the new APIs, and detect |
45 | | - * the actual version at runtime in order to call the relevant methods. |
| 36 | + * <p>We detect the actual version at runtime in order to call the relevant methods. |
46 | 37 | * |
47 | 38 | * <p>This is a hack, and might not work with subsequent Guava releases; the real fix is to stop |
48 | 39 | * exposing Guava in our public API. We'll address that in version 4 of the driver. |
@@ -188,84 +179,18 @@ public abstract <I, O> ListenableFuture<O> transformAsync( |
188 | 179 | * <p>The method {@code HostAndPort.getHostText} has been replaced with {@code |
189 | 180 | * HostAndPort.getHost} starting with Guava 20.0; it has been completely removed in Guava 22.0. |
190 | 181 | */ |
191 | | - @SuppressWarnings("JavaReflectionMemberAccess") |
192 | 182 | public String getHost(HostAndPort hostAndPort) { |
193 | | - try { |
194 | | - // Guava >= 20.0 |
195 | | - return (String) HostAndPort.class.getMethod("getHost").invoke(hostAndPort); |
196 | | - } catch (Exception e) { |
197 | | - // Guava < 22.0 |
198 | | - return hostAndPort.getHostText(); |
199 | | - } |
| 183 | + // Guava >= 20.0 |
| 184 | + return hostAndPort.getHost(); |
200 | 185 | } |
201 | 186 |
|
202 | 187 | private static GuavaCompatibility selectImplementation() { |
203 | 188 | if (isGuava_19_0_OrHigher()) { |
204 | 189 | logger.info("Detected Guava >= 19 in the classpath, using modern compatibility layer"); |
205 | 190 | return new Version19OrHigher(); |
206 | | - } else if (isGuava_16_0_1_OrHigher()) { |
207 | | - logger.info("Detected Guava < 19 in the classpath, using legacy compatibility layer"); |
208 | | - return new Version18OrLower(); |
209 | 191 | } else { |
210 | 192 | throw new DriverInternalError( |
211 | | - "Detected incompatible version of Guava in the classpath. " |
212 | | - + "You need 16.0.1 or higher."); |
213 | | - } |
214 | | - } |
215 | | - |
216 | | - private static class Version18OrLower extends GuavaCompatibility { |
217 | | - |
218 | | - @Override |
219 | | - public <V> ListenableFuture<V> withFallback( |
220 | | - ListenableFuture<? extends V> input, final AsyncFunction<Throwable, V> fallback) { |
221 | | - return Futures.withFallback( |
222 | | - input, |
223 | | - new com.google.common.util.concurrent.FutureFallback<V>() { |
224 | | - @Override |
225 | | - public ListenableFuture<V> create(Throwable t) throws Exception { |
226 | | - return fallback.apply(t); |
227 | | - } |
228 | | - }); |
229 | | - } |
230 | | - |
231 | | - @Override |
232 | | - public <V> ListenableFuture<V> withFallback( |
233 | | - ListenableFuture<? extends V> input, |
234 | | - final AsyncFunction<Throwable, V> fallback, |
235 | | - Executor executor) { |
236 | | - return Futures.withFallback( |
237 | | - input, |
238 | | - new com.google.common.util.concurrent.FutureFallback<V>() { |
239 | | - @Override |
240 | | - public ListenableFuture<V> create(Throwable t) throws Exception { |
241 | | - return fallback.apply(t); |
242 | | - } |
243 | | - }, |
244 | | - executor); |
245 | | - } |
246 | | - |
247 | | - @Override |
248 | | - public <I, O> ListenableFuture<O> transformAsync( |
249 | | - ListenableFuture<I> input, AsyncFunction<? super I, ? extends O> function) { |
250 | | - return Futures.transform(input, function); |
251 | | - } |
252 | | - |
253 | | - @Override |
254 | | - public <I, O> ListenableFuture<O> transformAsync( |
255 | | - ListenableFuture<I> input, |
256 | | - AsyncFunction<? super I, ? extends O> function, |
257 | | - Executor executor) { |
258 | | - return Futures.transform(input, function, executor); |
259 | | - } |
260 | | - |
261 | | - @Override |
262 | | - public boolean isSupertypeOf(TypeToken<?> target, TypeToken<?> argument) { |
263 | | - return target.isAssignableFrom(argument); |
264 | | - } |
265 | | - |
266 | | - @Override |
267 | | - public Executor sameThreadExecutor() { |
268 | | - return MoreExecutors.sameThreadExecutor(); |
| 193 | + "Detected incompatible version of Guava in the classpath. " + "You need 19.0 or higher."); |
269 | 194 | } |
270 | 195 | } |
271 | 196 |
|
@@ -319,30 +244,6 @@ private static boolean isGuava_19_0_OrHigher() { |
319 | 244 | Executor.class); |
320 | 245 | } |
321 | 246 |
|
322 | | - private static boolean isGuava_16_0_1_OrHigher() { |
323 | | - // Cheap check for < 16.0 |
324 | | - if (!methodExists(Maps.class, "asConverter", BiMap.class)) { |
325 | | - return false; |
326 | | - } |
327 | | - // More elaborate check to filter out 16.0, which has a bug in TypeToken. We need 16.0.1. |
328 | | - boolean resolved = false; |
329 | | - TypeToken<Map<String, String>> mapOfString = TypeTokens.mapOf(String.class, String.class); |
330 | | - Type type = mapOfString.getType(); |
331 | | - if (type instanceof ParameterizedType) { |
332 | | - ParameterizedType pType = (ParameterizedType) type; |
333 | | - Type[] types = pType.getActualTypeArguments(); |
334 | | - if (types.length == 2) { |
335 | | - TypeToken valueType = TypeToken.of(types[1]); |
336 | | - resolved = valueType.getRawType().equals(String.class); |
337 | | - } |
338 | | - } |
339 | | - if (!resolved) { |
340 | | - logger.debug( |
341 | | - "Detected Guava issue #1635 which indicates that version 16.0 is in the classpath"); |
342 | | - } |
343 | | - return resolved; |
344 | | - } |
345 | | - |
346 | 247 | private static boolean methodExists( |
347 | 248 | Class<?> declaringClass, String methodName, Class<?>... parameterTypes) { |
348 | 249 | try { |
|
0 commit comments