diff --git a/java/dagger/hilt/android/internal/testing/EarlySingletonComponentCreator.java b/java/dagger/hilt/android/internal/testing/EarlySingletonComponentCreator.java index 8e61e4aff01..1dbb73ab16a 100644 --- a/java/dagger/hilt/android/internal/testing/EarlySingletonComponentCreator.java +++ b/java/dagger/hilt/android/internal/testing/EarlySingletonComponentCreator.java @@ -23,6 +23,11 @@ public abstract class EarlySingletonComponentCreator { private static final String EARLY_SINGLETON_COMPONENT_CREATOR_IMPL = "dagger.hilt.android.internal.testing.EarlySingletonComponentCreatorImpl"; + private static final String ERROR_MSG = + "The EarlyComponent was requested but does not exist. Check that you have annotated " + + "your test class with @HiltAndroidTest and that the processor is running over your " + + "test."; + static Object createComponent() { try { return Class.forName(EARLY_SINGLETON_COMPONENT_CREATOR_IMPL) @@ -30,16 +35,19 @@ static Object createComponent() { .getDeclaredConstructor() .newInstance() .create(); - } catch (ClassNotFoundException - | NoSuchMethodException - | IllegalAccessException - | InstantiationException - | InvocationTargetException e) { - throw new RuntimeException( - "The EarlyComponent was requested but does not exist. Check that you have annotated " - + "your test class with @HiltAndroidTest and that the processor is running over your " - + "test.", - e); + // We catch each individual exception rather than using a multicatch because multi-catch will + // get compiled to the common but new super type ReflectiveOperationException, which is not + // allowed on API < 19. See b/187826710. + } catch (ClassNotFoundException e) { + throw new RuntimeException(ERROR_MSG, e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(ERROR_MSG, e); + } catch (IllegalAccessException e) { + throw new RuntimeException(ERROR_MSG, e); + } catch (InstantiationException e) { + throw new RuntimeException(ERROR_MSG, e); + } catch (InvocationTargetException e) { + throw new RuntimeException(ERROR_MSG, e); } } diff --git a/java/dagger/hilt/android/internal/testing/TestComponentDataSupplier.java b/java/dagger/hilt/android/internal/testing/TestComponentDataSupplier.java index b6f8b0b455d..b1234ddb04e 100644 --- a/java/dagger/hilt/android/internal/testing/TestComponentDataSupplier.java +++ b/java/dagger/hilt/android/internal/testing/TestComponentDataSupplier.java @@ -32,22 +32,31 @@ static TestComponentData get(Class testClass) { .getDeclaredConstructor() .newInstance() .get(); - } catch (ClassNotFoundException - | NoSuchMethodException - | IllegalAccessException - | InstantiationException - | InvocationTargetException e) { - throw new RuntimeException( - String.format( - "Hilt test, %s, is missing generated file: %s. Check that the test class is " - + " annotated with @HiltAndroidTest and that the processor is running over your" - + " test.", - testClass.getSimpleName(), - generatedClassName), - e); + // We catch each individual exception rather than using a multicatch because multi-catch will + // get compiled to the common but new super type ReflectiveOperationException, which is not + // allowed on API < 19. See b/187826710. + } catch (ClassNotFoundException e) { + throw new RuntimeException(errorMessage(testClass, generatedClassName), e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(errorMessage(testClass, generatedClassName), e); + } catch (IllegalAccessException e) { + throw new RuntimeException(errorMessage(testClass, generatedClassName), e); + } catch (InstantiationException e) { + throw new RuntimeException(errorMessage(testClass, generatedClassName), e); + } catch (InvocationTargetException e) { + throw new RuntimeException(errorMessage(testClass, generatedClassName), e); } } + private static String errorMessage(Class testClass, String generatedClassName) { + return String.format( + "Hilt test, %s, is missing generated file: %s. Check that the test class is " + + " annotated with @HiltAndroidTest and that the processor is running over your" + + " test.", + testClass.getSimpleName(), + generatedClassName); + } + private static String getEnclosedClassName(Class testClass) { StringBuilder sb = new StringBuilder(); Class currClass = testClass;