aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcnester <cnester@google.com>2015-03-02 10:11:36 -0800
committerSam Berlin <sameb@google.com>2015-03-23 18:27:17 -0400
commitfb04caeeadfea0ba966bcfe633aa5ec3f8046cbf (patch)
tree658d7c02d131b5031140ff2ad1e886d5020840e5
parent156c8cc762fab971efb727c7ab107fa243be2fc9 (diff)
downloadguice-fb04caeeadfea0ba966bcfe633aa5ec3f8046cbf.tar.gz
Add ability to not scope exception to RemoteProviderBinder
------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=87524840
-rw-r--r--extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java12
-rw-r--r--extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java9
-rw-r--r--extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java7
-rw-r--r--extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java104
-rw-r--r--extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java88
-rw-r--r--extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java74
6 files changed, 256 insertions, 38 deletions
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java
index f65b6d2f..a76d64cb 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethod.java
@@ -50,6 +50,7 @@ class CheckedProviderMethod<T> implements CheckedProvider<T>, HasDependencies {
private final boolean exposed;
private final Class<? extends CheckedProvider> checkedProvider;
private final List<TypeLiteral<?>> exceptionTypes;
+ private final boolean scopeExceptions;
CheckedProviderMethod(
Key<T> key,
@@ -59,7 +60,8 @@ class CheckedProviderMethod<T> implements CheckedProvider<T>, HasDependencies {
List<Provider<?>> parameterProviders,
Class<? extends Annotation> scopeAnnotation,
Class<? extends CheckedProvider> checkedProvider,
- List<TypeLiteral<?>> exceptionTypes) {
+ List<TypeLiteral<?>> exceptionTypes,
+ boolean scopeExceptions) {
this.key = key;
this.scopeAnnotation = scopeAnnotation;
this.instance = instance;
@@ -69,6 +71,7 @@ class CheckedProviderMethod<T> implements CheckedProvider<T>, HasDependencies {
this.exposed = method.isAnnotationPresent(Exposed.class);
this.checkedProvider = checkedProvider;
this.exceptionTypes = exceptionTypes;
+ this.scopeExceptions = scopeExceptions;
method.setAccessible(true);
}
@@ -77,13 +80,14 @@ class CheckedProviderMethod<T> implements CheckedProvider<T>, HasDependencies {
binder = binder.withSource(method);
SecondaryBinder<?, ?> sbinder =
- ThrowingProviderBinder.create(binder)
- .bind(checkedProvider, key.getTypeLiteral());
+ ThrowingProviderBinder.create(binder)
+ .bind(checkedProvider, key.getTypeLiteral());
if(key.getAnnotation() != null) {
sbinder = sbinder.annotatedWith(key.getAnnotation());
} else if(key.getAnnotationType() != null) {
sbinder = sbinder.annotatedWith(key.getAnnotationType());
- }
+ }
+ sbinder.scopeExceptions(scopeExceptions);
ScopedBindingBuilder sbbuilder = sbinder.toProviderMethod(this);
if(scopeAnnotation != null) {
sbbuilder.in(scopeAnnotation);
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
index dce2bfa9..f88c5078 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
@@ -79,7 +79,7 @@ final class CheckedProviderMethodsModule implements Module {
for (Method method : c.getDeclaredMethods()) {
CheckedProvides checkedProvides = method.getAnnotation(CheckedProvides.class);
if(checkedProvides != null) {
- result.add(createProviderMethod(binder, method, checkedProvides.value()));
+ result.add(createProviderMethod(binder, method, checkedProvides));
}
}
}
@@ -87,7 +87,9 @@ final class CheckedProviderMethodsModule implements Module {
}
<T> CheckedProviderMethod<T> createProviderMethod(Binder binder, final Method method,
- Class<? extends CheckedProvider> throwingProvider) {
+ CheckedProvides checkedProvides) {
+ @SuppressWarnings("rawtypes")
+ Class<? extends CheckedProvider> throwingProvider = checkedProvides.value();
binder = binder.withSource(method);
Errors errors = new Errors(method);
@@ -123,7 +125,8 @@ final class CheckedProviderMethodsModule implements Module {
}
return new CheckedProviderMethod<T>(key, method, delegate, ImmutableSet.copyOf(dependencies),
- parameterProviders, scopeAnnotation, throwingProvider, exceptionTypes);
+ parameterProviders, scopeAnnotation, throwingProvider, exceptionTypes,
+ checkedProvides.scopeExceptions());
}
<T> Key<T> getKey(Errors errors, TypeLiteral<T> type, Member member, Annotation[] annotations) {
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java
index b702dcc8..c7bfaedc 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvides.java
@@ -42,5 +42,10 @@ public @interface CheckedProvides {
* The interface that provides this value, a subinterface of {@link CheckedProvider}.
*/
Class<? extends CheckedProvider> value();
-
+
+ /**
+ * Whether exceptions should be put into the Guice scope.
+ * Default behavior is that exceptions are scoped.
+ */
+ boolean scopeExceptions() default true;
}
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
index 637099ac..de33d2c7 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/ThrowingProviderBinder.java
@@ -85,6 +85,12 @@ import java.util.Set;
*/
public class ThrowingProviderBinder {
+ private static final TypeLiteral<CheckedProvider<?>> CHECKED_PROVIDER_TYPE
+ = new TypeLiteral<CheckedProvider<?>>() { };
+
+ private static final TypeLiteral<CheckedProviderMethod<?>> CHECKED_PROVIDER_METHOD_TYPE
+ = new TypeLiteral<CheckedProviderMethod<?>>() { };
+
private final Binder binder;
private ThrowingProviderBinder(Binder binder) {
@@ -134,6 +140,7 @@ public class ThrowingProviderBinder {
private Class<? extends Annotation> annotationType;
private Annotation annotation;
private Key<P> interfaceKey;
+ private boolean scopeExceptions = true;
public SecondaryBinder(Class<P> interfaceType, Type valueType) {
this.interfaceType = checkNotNull(interfaceType, "interfaceType");
@@ -171,6 +178,15 @@ public class ThrowingProviderBinder {
return this;
}
+ /**
+ * Determines if exceptions should be scoped. By default exceptions are scoped.
+ * @param scopeExceptions whether exceptions should be scoped.
+ */
+ public SecondaryBinder<P, T> scopeExceptions(boolean scopeExceptions) {
+ this.scopeExceptions = scopeExceptions;
+ return this;
+ }
+
public ScopedBindingBuilder to(P target) {
Key<P> targetKey = Key.get(interfaceType, UniqueAnnotations.create());
binder.bind(targetKey).toInstance(target);
@@ -236,28 +252,32 @@ public class ThrowingProviderBinder {
}
};
- Key<CheckedProvider> targetKey = Key.get(CheckedProvider.class, UniqueAnnotations.create());
+ Key<CheckedProvider<?>> targetKey = Key.get(CHECKED_PROVIDER_TYPE,
+ UniqueAnnotations.create());
binder.bind(targetKey).toInstance(checkedProvider);
return toInternal(targetKey);
}
ScopedBindingBuilder toProviderMethod(CheckedProviderMethod<?> target) {
- Key<CheckedProviderMethod> targetKey =
- Key.get(CheckedProviderMethod.class, UniqueAnnotations.create());
+ Key<CheckedProviderMethod<?>> targetKey =
+ Key.get(CHECKED_PROVIDER_METHOD_TYPE, UniqueAnnotations.create());
binder.bind(targetKey).toInstance(target);
return toInternal(targetKey);
}
+ @SuppressWarnings("unchecked") // P only extends the raw type of CheckedProvider
public ScopedBindingBuilder to(Key<? extends P> targetKey) {
checkNotNull(targetKey, "targetKey");
- return toInternal(targetKey);
+ return toInternal((Key<? extends CheckedProvider<?>>)targetKey);
}
- private ScopedBindingBuilder toInternal(final Key<? extends CheckedProvider> targetKey) {
+ private ScopedBindingBuilder toInternal(final Key<? extends CheckedProvider<?>> targetKey) {
final Key<Result> resultKey = Key.get(Result.class, UniqueAnnotations.create());
+ // Note that this provider will behave like the final provider Guice creates.
+ // It will especially do scoping if the user adds that.
final Provider<Result> resultProvider = binder.getProvider(resultKey);
- final Provider<? extends CheckedProvider> targetProvider = binder.getProvider(targetKey);
+ final Provider<? extends CheckedProvider<?>> targetProvider = binder.getProvider(targetKey);
interfaceKey = createKey();
// don't bother binding the proxy type if this is in an invalid state.
@@ -272,31 +292,63 @@ public class ThrowingProviderBinder {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
- return resultProvider.get().getOrThrow();
+
+ if (scopeExceptions) {
+ return resultProvider.get().getOrThrow();
+ } else {
+ Result result;
+ try {
+ result = resultProvider.get();
+ } catch (ProvisionException pe) {
+ Throwable cause = pe.getCause();
+ if (cause instanceof ResultException) {
+ throw ((ResultException)cause).getCause();
+ } else {
+ throw pe;
+ }
+ }
+ return result.getOrThrow();
+ }
}
}));
+ @Override
public P get() {
return instance;
}
-
+
+ @Override
public Set<Dependency<?>> getDependencies() {
return ImmutableSet.<Dependency<?>>of(Dependency.get(resultKey));
}
});
}
- return binder.bind(resultKey).toProvider(new ProviderWithDependencies<Result>() {
+ // The provider is unscoped, but the user may apply a scope to it through the
+ // ScopedBindingBuilder this returns.
+ return binder.bind(resultKey).toProvider(
+ createResultProvider(targetKey, targetProvider));
+ }
+
+ private ProviderWithDependencies<Result> createResultProvider(
+ final Key<? extends CheckedProvider<?>> targetKey,
+ final Provider<? extends CheckedProvider<?>> targetProvider) {
+ return new ProviderWithDependencies<Result>() {
+ @Override
public Result get() {
try {
return Result.forValue(targetProvider.get().get());
} catch (Exception e) {
- for(Class<? extends Throwable> exceptionType : exceptionTypes) {
+ for (Class<? extends Throwable> exceptionType : exceptionTypes) {
if (exceptionType.isInstance(e)) {
- return Result.forException(e);
+ if (scopeExceptions) {
+ return Result.forException(e);
+ } else {
+ throw new ResultException(e);
+ }
}
}
-
+
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
@@ -305,13 +357,14 @@ public class ThrowingProviderBinder {
}
}
}
-
+
+ @Override
public Set<Dependency<?>> getDependencies() {
return ImmutableSet.<Dependency<?>>of(Dependency.get(targetKey));
}
- });
+ };
}
-
+
/**
* Returns the exception type declared to be thrown by the get method of
* {@code interfaceType}.
@@ -455,10 +508,12 @@ public class ThrowingProviderBinder {
}
/**
- * Represents the returned value from a call to {@link
- * CheckedProvider#get()}. This is the value that will be scoped by Guice.
+ * Represents the returned value from a call to {@link CheckedProvider#get()}. This is the value
+ * that will be scoped by Guice.
*/
static class Result implements Serializable {
+ private static final long serialVersionUID = 0L;
+
private final Object value;
private final Exception exception;
@@ -474,7 +529,7 @@ public class ThrowingProviderBinder {
public static Result forException(Exception e) {
return new Result(null, e);
}
-
+
public Object getOrThrow() throws Exception {
if (exception != null) {
throw exception;
@@ -482,8 +537,17 @@ public class ThrowingProviderBinder {
return value;
}
}
-
- private static final long serialVersionUID = 0L;
+ }
+
+ /**
+ * RuntimeException class to wrap exceptions from the checked provider.
+ * The regular guice provider can throw it and the checked provider proxy extracts
+ * the underlying exception and rethrows it.
+ */
+ private static class ResultException extends RuntimeException {
+ ResultException(Exception cause) {
+ super(cause);
+ }
}
private static class NotSyntheticOrBridgePredicate implements Predicate<Method> {
diff --git a/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
index 7a640bea..1f4f9775 100644
--- a/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
+++ b/extensions/throwingproviders/test/com/google/inject/throwingproviders/CheckedProviderTest.java
@@ -16,6 +16,9 @@
package com.google.inject.throwingproviders;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -23,6 +26,7 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.AbstractModule;
import com.google.inject.Asserts;
+import com.google.inject.BindingAnnotation;
import com.google.inject.CreationException;
import com.google.inject.Guice;
import com.google.inject.Inject;
@@ -45,6 +49,7 @@ import com.google.inject.throwingproviders.ThrowingProviderBinder.Result;
import junit.framework.TestCase;
import java.io.IOException;
+import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -64,6 +69,8 @@ import java.util.TooManyListenersException;
* @author sameb@google.com (Sam Berlin)
*/
public class CheckedProviderTest extends TestCase {
+ @Target(METHOD) @Retention(RUNTIME) @BindingAnnotation
+ @interface NotExceptionScoping { };
private static final Function<Dependency<?>, Key<?>> DEPENDENCY_TO_KEY =
new Function<Dependency<?>, Key<?>>() {
@@ -95,6 +102,14 @@ public class CheckedProviderTest extends TestCase {
.bind(RemoteProvider.class, Foo.class)
.to(mockRemoteProvider)
.in(testScope);
+
+ ThrowingProviderBinder.create(binder())
+ .bind(RemoteProvider.class, Foo.class)
+ .annotatedWith(NotExceptionScoping.class)
+ .scopeExceptions(false)
+ .to(mockRemoteProvider)
+ .in(testScope);
+
}
});
@@ -111,6 +126,15 @@ public class CheckedProviderTest extends TestCase {
Foo throwOrGet() throws RemoteException, BindException {
return mockRemoteProvider.get();
}
+
+ @SuppressWarnings("unused")
+ @CheckedProvides(value = RemoteProvider.class, scopeExceptions = false)
+ @NotExceptionScoping
+ @TestScope.Scoped
+ Foo notExceptionScopingThrowOrGet() throws RemoteException, BindException {
+ return mockRemoteProvider.get();
+ }
+
});
cxtorInjector = Guice.createInjector(new AbstractModule() {
@@ -120,6 +144,14 @@ public class CheckedProviderTest extends TestCase {
.bind(RemoteProvider.class, Foo.class)
.providing(MockFoo.class)
.in(testScope);
+
+ ThrowingProviderBinder.create(binder())
+ .bind(RemoteProvider.class, Foo.class)
+ .annotatedWith(NotExceptionScoping.class)
+ .scopeExceptions(false)
+ .providing(MockFoo.class)
+ .in(testScope);
+
}
});
}
@@ -151,17 +183,28 @@ public class CheckedProviderTest extends TestCase {
}
public void testValuesScoped_Bind() throws Exception {
- tValuesScoped(bindInjector);
+ tValuesScoped(bindInjector, null);
}
public void testValuesScoped_Provides() throws Exception {
- tValuesScoped(providesInjector);
+ tValuesScoped(providesInjector, null);
}
- private void tValuesScoped(Injector injector) throws Exception {
- RemoteProvider<Foo> remoteProvider =
- injector.getInstance(Key.get(remoteProviderOfFoo));
+ public void testValuesScopedWhenNotExceptionScoping_Bind() throws Exception {
+ tValuesScoped(bindInjector, NotExceptionScoping.class);
+ }
+
+ public void testValuesScopedWhenNotExceptionScoping_Provides() throws Exception {
+ tValuesScoped(providesInjector, NotExceptionScoping.class);
+ }
+ private void tValuesScoped(Injector injector,
+ Class<? extends Annotation> annotation) throws Exception {
+ Key<RemoteProvider<Foo>> key = annotation != null ?
+ Key.get(remoteProviderOfFoo, annotation) :
+ Key.get(remoteProviderOfFoo);
+ RemoteProvider<Foo> remoteProvider = injector.getInstance(key);
+
mockRemoteProvider.setNextToReturn(new SimpleFoo("A"));
assertEquals("A", remoteProvider.get().s());
@@ -218,6 +261,41 @@ public class CheckedProviderTest extends TestCase {
}
}
+ public void testExceptionsNotScopedWhenNotExceptionScoping_Bind() throws Exception {
+ tExceptionsNotScopedWhenNotExceptionScoping(bindInjector);
+ }
+
+ public void testExceptionsNotScopedWhenNotExceptionScoping_Provides() throws Exception {
+ tExceptionsNotScopedWhenNotExceptionScoping(providesInjector);
+ }
+
+ public void testExceptionNotScopedWhenNotExceptionScoping_Cxtor() throws Exception {
+ tExceptionsNotScopedWhenNotExceptionScoping(cxtorInjector);
+ }
+
+ private void tExceptionsNotScopedWhenNotExceptionScoping(Injector injector) throws Exception {
+ RemoteProvider<Foo> remoteProvider =
+ injector.getInstance(Key.get(remoteProviderOfFoo, NotExceptionScoping.class));
+
+ mockRemoteProvider.throwOnNextGet(new RemoteException("A"));
+ MockFoo.nextToThrow = new RemoteException("A");
+ try {
+ remoteProvider.get();
+ fail();
+ } catch (RemoteException expected) {
+ assertEquals("A", expected.getMessage());
+ }
+
+ mockRemoteProvider.throwOnNextGet(new RemoteException("B"));
+ MockFoo.nextToThrow = new RemoteException("B");
+ try {
+ remoteProvider.get();
+ fail();
+ } catch (RemoteException expected) {
+ assertEquals("B", expected.getMessage());
+ }
+ }
+
public void testAnnotations_Bind() throws Exception {
final MockRemoteProvider<Foo> mockRemoteProviderA = new MockRemoteProvider<Foo>();
final MockRemoteProvider<Foo> mockRemoteProviderB = new MockRemoteProvider<Foo>();
diff --git a/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java b/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java
index d56cb7dc..373c68d2 100644
--- a/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java
+++ b/extensions/throwingproviders/test/com/google/inject/throwingproviders/ThrowingProviderTest.java
@@ -16,11 +16,15 @@
package com.google.inject.throwingproviders;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
+import com.google.inject.BindingAnnotation;
import com.google.inject.CreationException;
import com.google.inject.Guice;
import com.google.inject.Inject;
@@ -37,6 +41,9 @@ import com.google.inject.spi.Message;
import junit.framework.TestCase;
import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
import java.rmi.AccessException;
import java.rmi.RemoteException;
import java.util.Arrays;
@@ -50,6 +57,8 @@ import java.util.TooManyListenersException;
*/
@SuppressWarnings("deprecation")
public class ThrowingProviderTest extends TestCase {
+ @Target(METHOD) @Retention(RUNTIME) @BindingAnnotation
+ @interface NotExceptionScoping { };
private final TypeLiteral<RemoteProvider<String>> remoteProviderOfString
= new TypeLiteral<RemoteProvider<String>>() { };
@@ -61,6 +70,13 @@ public class ThrowingProviderTest extends TestCase {
.bind(RemoteProvider.class, String.class)
.to(mockRemoteProvider)
.in(testScope);
+
+ ThrowingProviderBinder.create(binder())
+ .bind(RemoteProvider.class, String.class)
+ .annotatedWith(NotExceptionScoping.class)
+ .scopeExceptions(false)
+ .to(mockRemoteProvider)
+ .in(testScope);
}
});
private Injector providesInjector = Guice.createInjector(new AbstractModule() {
@@ -75,6 +91,14 @@ public class ThrowingProviderTest extends TestCase {
String throwOrGet() throws RemoteException {
return mockRemoteProvider.get();
}
+
+ @SuppressWarnings("unused")
+ @CheckedProvides(value = RemoteProvider.class, scopeExceptions = false)
+ @NotExceptionScoping
+ @TestScope.Scoped
+ String notExceptionScopingThrowOrGet() throws RemoteException {
+ return mockRemoteProvider.get();
+ }
});
public void testExceptionsThrown_Bind() {
@@ -99,16 +123,27 @@ public class ThrowingProviderTest extends TestCase {
}
public void testValuesScoped_Bind() throws RemoteException {
- tValuesScoped(bindInjector);
+ tValuesScoped(bindInjector, null);
}
public void testValuesScoped_Provides() throws RemoteException {
- tValuesScoped(providesInjector);
+ tValuesScoped(providesInjector, null);
}
- private void tValuesScoped(Injector injector) throws RemoteException {
- RemoteProvider<String> remoteProvider =
- injector.getInstance(Key.get(remoteProviderOfString));
+ public void testValuesScopedWhenNotExceptionScoping_Bind() throws RemoteException {
+ tValuesScoped(bindInjector, NotExceptionScoping.class);
+ }
+
+ public void testValuesScopedWhenNotExceptionScoping_Provides() throws RemoteException {
+ tValuesScoped(providesInjector, NotExceptionScoping.class);
+ }
+
+ private void tValuesScoped(Injector injector, Class<? extends Annotation> annotation)
+ throws RemoteException {
+ Key<RemoteProvider<String>> key = annotation != null ?
+ Key.get(remoteProviderOfString, annotation) :
+ Key.get(remoteProviderOfString);
+ RemoteProvider<String> remoteProvider = injector.getInstance(key);
mockRemoteProvider.setNextToReturn("A");
assertEquals("A", remoteProvider.get());
@@ -148,6 +183,35 @@ public class ThrowingProviderTest extends TestCase {
assertEquals("A", expected.getMessage());
}
}
+
+ public void testExceptionsNotScopedWhenNotExceptionScoping_Bind() {
+ tExceptionsNotScopedWhenNotExceptionScoping(bindInjector);
+ }
+
+ public void testExceptionsNotScopedWhenNotExceptionScoping_Provides() {
+ tExceptionsNotScopedWhenNotExceptionScoping(providesInjector);
+ }
+
+ private void tExceptionsNotScopedWhenNotExceptionScoping(Injector injector) {
+ RemoteProvider<String> remoteProvider =
+ injector.getInstance(Key.get(remoteProviderOfString, NotExceptionScoping.class));
+
+ mockRemoteProvider.throwOnNextGet("A");
+ try {
+ remoteProvider.get();
+ fail();
+ } catch (RemoteException expected) {
+ assertEquals("A", expected.getMessage());
+ }
+
+ mockRemoteProvider.throwOnNextGet("B");
+ try {
+ remoteProvider.get();
+ fail();
+ } catch (RemoteException expected) {
+ assertEquals("B", expected.getMessage());
+ }
+ }
public void testAnnotations_Bind() throws RemoteException {
final MockRemoteProvider<String> mockRemoteProviderA = new MockRemoteProvider<String>();