Fixing a old bug wherein calling "Provider.get()" inside of an existing scope would kill the internal context and leave the injector in an inconsistent state.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@1032 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/internal/InjectorBuilder.java b/src/com/google/inject/internal/InjectorBuilder.java
index cea61dc..0f80f41 100644
--- a/src/com/google/inject/internal/InjectorBuilder.java
+++ b/src/com/google/inject/internal/InjectorBuilder.java
@@ -195,14 +195,14 @@
injector.callInContext(new ContextualCallable<Void>() {
Dependency<?> dependency = Dependency.get(binding.getKey());
public Void call(InternalContext context) {
- context.setDependency(dependency);
+ Dependency previous = context.setDependency(dependency);
Errors errorsForBinding = errors.withSource(dependency);
try {
binding.getInternalFactory().get(errorsForBinding, context, dependency);
} catch (ErrorsException e) {
errorsForBinding.merge(e.getErrors());
} finally {
- context.setDependency(null);
+ context.setDependency(previous);
}
return null;
diff --git a/src/com/google/inject/internal/InjectorImpl.java b/src/com/google/inject/internal/InjectorImpl.java
index d986e48..b55014e 100644
--- a/src/com/google/inject/internal/InjectorImpl.java
+++ b/src/com/google/inject/internal/InjectorImpl.java
@@ -727,11 +727,11 @@
try {
T t = callInContext(new ContextualCallable<T>() {
public T call(InternalContext context) throws ErrorsException {
- context.setDependency(dependency);
+ Dependency previous = context.setDependency(dependency);
try {
return factory.get(errors, context, dependency);
} finally {
- context.setDependency(null);
+ context.setDependency(previous);
}
}
});
diff --git a/src/com/google/inject/internal/InternalContext.java b/src/com/google/inject/internal/InternalContext.java
index 40b6132..c772910 100644
--- a/src/com/google/inject/internal/InternalContext.java
+++ b/src/com/google/inject/internal/InternalContext.java
@@ -45,7 +45,9 @@
return dependency;
}
- public void setDependency(Dependency dependency) {
+ public Dependency setDependency(Dependency dependency) {
+ Dependency previous = dependency;
this.dependency = dependency;
+ return previous;
}
}
diff --git a/src/com/google/inject/internal/SingleFieldInjector.java b/src/com/google/inject/internal/SingleFieldInjector.java
index 3614105..aa8b73f 100644
--- a/src/com/google/inject/internal/SingleFieldInjector.java
+++ b/src/com/google/inject/internal/SingleFieldInjector.java
@@ -47,7 +47,7 @@
public void inject(Errors errors, InternalContext context, Object o) {
errors = errors.withSource(dependency);
- context.setDependency(dependency);
+ Dependency previous = context.setDependency(dependency);
try {
Object value = factory.get(errors, context, dependency);
field.set(o, value);
@@ -56,7 +56,7 @@
} catch (IllegalAccessException e) {
throw new AssertionError(e); // a security manager is blocking us, we're hosed
} finally {
- context.setDependency(null);
+ context.setDependency(previous);
}
}
}
diff --git a/src/com/google/inject/internal/SingleParameterInjector.java b/src/com/google/inject/internal/SingleParameterInjector.java
index 1f2de9d..9b4cb00 100644
--- a/src/com/google/inject/internal/SingleParameterInjector.java
+++ b/src/com/google/inject/internal/SingleParameterInjector.java
@@ -33,11 +33,11 @@
}
private T inject(Errors errors, InternalContext context) throws ErrorsException {
- context.setDependency(dependency);
+ Dependency previous = context.setDependency(dependency);
try {
return factory.get(errors.withSource(dependency), context, dependency);
} finally {
- context.setDependency(null);
+ context.setDependency(previous);
}
}
diff --git a/src/com/google/inject/spi/Dependency.java b/src/com/google/inject/spi/Dependency.java
index 8908518..e9d5650 100644
--- a/src/com/google/inject/spi/Dependency.java
+++ b/src/com/google/inject/spi/Dependency.java
@@ -20,6 +20,7 @@
import com.google.inject.internal.ImmutableSet;
import com.google.inject.internal.Lists;
import com.google.inject.internal.Objects;
+import static com.google.inject.internal.Preconditions.checkNotNull;
import java.util.List;
import java.util.Set;
@@ -39,10 +40,9 @@
private final boolean nullable;
private final int parameterIndex;
- Dependency(InjectionPoint injectionPoint, Key<T> key,
- boolean nullable, int parameterIndex) {
+ Dependency(InjectionPoint injectionPoint, Key<T> key, boolean nullable, int parameterIndex) {
this.injectionPoint = injectionPoint;
- this.key = key;
+ this.key = checkNotNull(key, "key");
this.nullable = nullable;
this.parameterIndex = parameterIndex;
}
diff --git a/test/com/google/inject/ScopesTest.java b/test/com/google/inject/ScopesTest.java
index 980a77f..ca354fc 100644
--- a/test/com/google/inject/ScopesTest.java
+++ b/test/com/google/inject/ScopesTest.java
@@ -415,4 +415,31 @@
return new ProvidedBySingleton();
}
}
+
+ public void testScopeThatGetsAnUnrelatedObject() {
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bind(B.class);
+ bind(C.class);
+ ProviderGetScope providerGetScope = new ProviderGetScope();
+ requestInjection(providerGetScope);
+ bindScope(CustomScoped.class, providerGetScope);
+ }
+ });
+
+ injector.getInstance(C.class);
+ }
+
+ class ProviderGetScope implements Scope {
+ @Inject Provider<B> bProvider;
+
+ public <T> Provider<T> scope(Key<T> key, final Provider<T> unscoped) {
+ return new Provider<T>() {
+ public T get() {
+ bProvider.get();
+ return unscoped.get();
+ }
+ };
+ }
+ }
}