Skip to content

Commit

Permalink
Use multicatch even when it produces the type `ReflectiveOperationExc…
Browse files Browse the repository at this point in the history
…eption`.

In `catch (IllegalAccessException | ClassNotFoundException e)`, for example, javac will infer the nearest common supertype, `ReflectiveOperationException`, as the type for `e`. With earlier Android versions this could be problematic. But `ReflectiveOperationException` is [available](https://developer.android.com/reference/java/lang/ReflectiveOperationException) under [KitKat](https://guava.dev/#important-warnings), which is good enough.

(And delete some special handling for "Java 7," which, back when we dropped support for Java 7, really became special handling for Android before [API Level 19](https://developer.android.com/reference/java/util/Currency#getAvailableCurrencies()).)

RELNOTES=n/a
PiperOrigin-RevId: 625710738
  • Loading branch information
cpovirk authored and Google Java Core Libraries committed Apr 17, 2024
1 parent eab5117 commit df2c2e5
Show file tree
Hide file tree
Showing 10 changed files with 12 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -372,14 +372,7 @@ private static <T> void setImplementation(Class<T> type, Class<? extends T> impl
constructor.setAccessible(true); // accessibility check is too slow
try {
return constructor.newInstance();
/*
* Do not merge the 2 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
* Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (InstantiationException impossible) {
throw new AssertionError(impossible);
} catch (IllegalAccessException impossible) {
} catch (InstantiationException | IllegalAccessException impossible) {
throw new AssertionError(impossible);
} catch (InvocationTargetException e) {
logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,37 +515,7 @@ Locale generateLocale() {

@Generates
Currency generateCurrency() {
try {
Method method = Currency.class.getMethod("getAvailableCurrencies");
@SuppressWarnings("unchecked") // getAvailableCurrencies() returns Set<Currency>.
Set<Currency> currencies = (Set<Currency>) method.invoke(null);
return pickInstance(currencies, Currency.getInstance(Locale.US));
/*
* Do not merge the 2 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
* Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (NoSuchMethodException notJava7) {
return preJava7FreshCurrency();
} catch (InvocationTargetException notJava7) {
return preJava7FreshCurrency();
} catch (IllegalAccessException impossible) {
throw new AssertionError(impossible);
}
}

private Currency preJava7FreshCurrency() {
for (Set<Locale> uselessLocales = Sets.newHashSet(); ; ) {
Locale locale = generateLocale();
if (uselessLocales.contains(locale)) { // exhausted all locales
return Currency.getInstance(Locale.US);
}
try {
return Currency.getInstance(locale);
} catch (IllegalArgumentException e) {
uselessLocales.add(locale);
}
}
return pickInstance(Currency.getAvailableCurrencies(), Currency.getInstance(Locale.US));
}

// common.base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -820,14 +820,12 @@ private static void assertTransformListIterator(List<String> list) {
try {
iterator.add("1");
fail("transformed list iterator is addable");
} catch (UnsupportedOperationException expected) {
} catch (IllegalStateException expected) {
} catch (UnsupportedOperationException | IllegalStateException expected) {
}
try {
iterator.set("1");
fail("transformed list iterator is settable");
} catch (UnsupportedOperationException expected) {
} catch (IllegalStateException expected) {
} catch (UnsupportedOperationException | IllegalStateException expected) {
}
}

Expand Down
9 changes: 1 addition & 8 deletions android/guava/src/com/google/common/reflect/Types.java
Original file line number Diff line number Diff line change
Expand Up @@ -596,14 +596,7 @@ String typeName(Type type) {
return (String) getTypeName.invoke(type);
} catch (NoSuchMethodException e) {
throw new AssertionError("Type.getTypeName should be available in Java 8");
/*
* Do not merge the 2 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
* Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
} catch (InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -834,16 +834,7 @@ public static ThreadFactory platformThreadFactory() {
Class.forName("com.google.appengine.api.ThreadManager")
.getMethod("currentRequestThreadFactory")
.invoke(null);
/*
* Do not merge the 3 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of Android
* don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (IllegalAccessException e) {
throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException e) {
throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
} catch (InvocationTargetException e) {
throw Throwables.propagate(e.getCause());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,7 @@ private static <T> void setImplementation(Class<T> type, Class<? extends T> impl
constructor.setAccessible(true); // accessibility check is too slow
try {
return constructor.newInstance();
/*
* Do not merge the 2 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
* Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (InstantiationException impossible) {
throw new AssertionError(impossible);
} catch (IllegalAccessException impossible) {
} catch (InstantiationException | IllegalAccessException impossible) {
throw new AssertionError(impossible);
} catch (InvocationTargetException e) {
logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,37 +519,7 @@ Locale generateLocale() {

@Generates
Currency generateCurrency() {
try {
Method method = Currency.class.getMethod("getAvailableCurrencies");
@SuppressWarnings("unchecked") // getAvailableCurrencies() returns Set<Currency>.
Set<Currency> currencies = (Set<Currency>) method.invoke(null);
return pickInstance(currencies, Currency.getInstance(Locale.US));
/*
* Do not merge the 2 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
* Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (NoSuchMethodException notJava7) {
return preJava7FreshCurrency();
} catch (InvocationTargetException notJava7) {
return preJava7FreshCurrency();
} catch (IllegalAccessException impossible) {
throw new AssertionError(impossible);
}
}

private Currency preJava7FreshCurrency() {
for (Set<Locale> uselessLocales = Sets.newHashSet(); ; ) {
Locale locale = generateLocale();
if (uselessLocales.contains(locale)) { // exhausted all locales
return Currency.getInstance(Locale.US);
}
try {
return Currency.getInstance(locale);
} catch (IllegalArgumentException e) {
uselessLocales.add(locale);
}
}
return pickInstance(Currency.getAvailableCurrencies(), Currency.getInstance(Locale.US));
}

@Empty
Expand Down
6 changes: 2 additions & 4 deletions guava-tests/test/com/google/common/collect/ListsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -820,14 +820,12 @@ private static void assertTransformListIterator(List<String> list) {
try {
iterator.add("1");
fail("transformed list iterator is addable");
} catch (UnsupportedOperationException expected) {
} catch (IllegalStateException expected) {
} catch (UnsupportedOperationException | IllegalStateException expected) {
}
try {
iterator.set("1");
fail("transformed list iterator is settable");
} catch (UnsupportedOperationException expected) {
} catch (IllegalStateException expected) {
} catch (UnsupportedOperationException | IllegalStateException expected) {
}
}

Expand Down
9 changes: 1 addition & 8 deletions guava/src/com/google/common/reflect/Types.java
Original file line number Diff line number Diff line change
Expand Up @@ -596,14 +596,7 @@ String typeName(Type type) {
return (String) getTypeName.invoke(type);
} catch (NoSuchMethodException e) {
throw new AssertionError("Type.getTypeName should be available in Java 8");
/*
* Do not merge the 2 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of
* Android don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
} catch (InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
Expand Down
11 changes: 1 addition & 10 deletions guava/src/com/google/common/util/concurrent/MoreExecutors.java
Original file line number Diff line number Diff line change
Expand Up @@ -912,16 +912,7 @@ public static ThreadFactory platformThreadFactory() {
Class.forName("com.google.appengine.api.ThreadManager")
.getMethod("currentRequestThreadFactory")
.invoke(null);
/*
* Do not merge the 3 catch blocks below. javac would infer a type of
* ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of Android
* don't *seem* to mind, but there might be edge cases of which we're unaware.)
*/
} catch (IllegalAccessException e) {
throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException e) {
throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
} catch (InvocationTargetException e) {
throw Throwables.propagate(e.getCause());
Expand Down

0 comments on commit df2c2e5

Please sign in to comment.