Author: limpbizkit
Date: Wed Jun 3 09:50:27 2009
New Revision: 994
Modified:
trunk/src/com/google/inject/InjectorImpl.java
trunk/test/com/google/inject/ParentInjectorTest.java
Log:
Fix for an embarassing bug reported by Dmitry Skavish.
http://groups.google.com/group/google-guice/browse_thread/thread/8f0a092727a0227c
We have a bunch of code for aggressively detecting many errors before
failing. Unfortunately, there was a situation where we'd detect an error
and keep going (to find more errors), but forget to ultimately throw the
error.
This resulted in polluting the JIT bindings cache, which breaks the world.
The fix is easiest to reproduce with Child Injectors, but I believe it's
also possible to poison the JIT bindings cache without child injectors.
Note:
The specific error we omit is the "Scope not found" error. In Guice 1.0, no
error was reported if a scope wasn't found. So although this is an
unfortunate problem, its not much worse than what we did previously. I
don't think it's necessary to cut a "Guice 2.0.1" for this problem. The
main difference is that the error impacts whether a binding will live in
parent or child injector.
Modified: trunk/src/com/google/inject/InjectorImpl.java
==============================================================================
--- trunk/src/com/google/inject/InjectorImpl.java (original)
+++ trunk/src/com/google/inject/InjectorImpl.java Wed Jun 3 09:50:27 2009
@@ -598,6 +598,8 @@
* @throws com.google.inject.internal.ErrorsException if the binding
cannot be created.
*/
<T> BindingImpl<T> createJustInTimeBinding(Key<T> key, Errors errors)
throws ErrorsException {
+ int numErrorsBefore = errors.size();
+
if (state.isBlacklisted(key)) {
throw errors.childBindingAlreadySet(key).toException();
}
@@ -642,6 +644,7 @@
Object source = key.getTypeLiteral().getRawType();
BindingImpl<T> binding = createUnitializedBinding(key,
Scoping.UNSCOPED, source, errors);
+ errors.throwIfNewErrors(numErrorsBefore);
initializeBinding(binding, errors);
return binding;
}
Modified: trunk/test/com/google/inject/ParentInjectorTest.java
==============================================================================
--- trunk/test/com/google/inject/ParentInjectorTest.java (original)
+++ trunk/test/com/google/inject/ParentInjectorTest.java Wed Jun 3
09:50:27 2009
@@ -216,6 +216,33 @@
assertNotNull(child.getProvider(F.class).get());
}
+ public void testErrorInParentButOkayInChild() {
+ Injector parent = Guice.createInjector();
+ Injector childInjector = parent.createChildInjector(new
AbstractModule() {
+ protected void configure() {
+ bindScope(MyScope.class, Scopes.SINGLETON);
+ bind(Object.class).to(F.class);
+ }
+ });
+ Object one = childInjector.getInstance(Object.class);
+ Object two = childInjector.getInstance(Object.class);
+ assertSame(one, two);
+ }
+
+ public void testErrorInParentAndChild() {
+ Injector parent = Guice.createInjector();
+ Injector childInjector = parent.createChildInjector();
+
+ try {
+ childInjector.getInstance(G.class);
+ fail();
+ } catch(ConfigurationException expected) {
+ assertContains(expected.getMessage(), "No scope is bound to " +
MyScope.class.getName(),
+ "at " + F.class.getName() + ".class(ParentInjectorTest.java:",
+ " while locating " + G.class.getName());
+ }
+ }
+
@Singleton
static class A {}
@@ -276,5 +303,8 @@
};
@MyScope
- static class F {}
+ static class F implements G {}
+
+ @ImplementedBy(F.class)
+ interface G {}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---