diff options
author | sameb <sameb@google.com> | 2014-12-18 14:44:16 -0800 |
---|---|---|
committer | Sam Berlin <sameb@google.com> | 2015-01-24 18:05:52 -0500 |
commit | 1bf1e9e0ddef515aaa41a70aa34821ff5564a71d (patch) | |
tree | c54fcdc9adcb3635284246b36340bfa628be33a9 | |
parent | ac3cf7c16fe991c6b027d1061034990802dff480 (diff) | |
download | guice-1bf1e9e0ddef515aaa41a70aa34821ff5564a71d.tar.gz |
Add the source of the binding when mapbinder/multibinder fail because of a null
binding.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=82465720
4 files changed, 80 insertions, 51 deletions
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java index f8fd4a3e..89df7713 100644 --- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java +++ b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java @@ -455,15 +455,16 @@ public abstract class MapBinder<K, V> { Key<V> valueKey = providerEntry.getValueKey(); Binding<V> valueBinding = injector.getBinding(valueKey); // If this isn't a dup due to an exact same binding, add it. - if (index.put(entry.getKey(), valueBinding.acceptTargetVisitor(indexer))) { - Provider<V> previous = providerMapMutable.put(entry.getKey(), entry.getValue()); + if (index.put(providerEntry.getKey(), valueBinding.acceptTargetVisitor(indexer))) { + Provider<V> previous = providerMapMutable.put(providerEntry.getKey(), + new ValueProvider<V>(providerEntry.getValue(), valueBinding)); if (previous != null && !permitDuplicates) { if (duplicateKeys == null) { duplicateKeys = Sets.newHashSet(); } - duplicateKeys.add(entry.getKey()); + duplicateKeys.add(providerEntry.getKey()); } - bindingsMutable.add(Maps.immutableEntry(entry.getKey(), valueBinding)); + bindingsMutable.add(Maps.immutableEntry(providerEntry.getKey(), valueBinding)); } } if (duplicateKeys != null) { @@ -529,9 +530,12 @@ public abstract class MapBinder<K, V> { Map<K, Object> map = new LinkedHashMap<K, Object>(mapProvider.get()); for (Entry<K, Object> entry : map.entrySet()) { @SuppressWarnings("unchecked") // we initialized the entries with providers - V value = ((Provider<V>) entry.getValue()).get(); + ValueProvider<V> provider = (ValueProvider<V>)entry.getValue(); + V value = provider.get(); checkConfiguration(value != null, - "Map injection failed due to null value for key \"%s\"", entry.getKey()); + "Map injection failed due to null value for key \"%s\", bound at: %s", + entry.getKey(), + provider.getValueBinding().getSource()); entry.setValue(value); } @SuppressWarnings("unchecked") // if we exited the loop then we replaced all Providers @@ -713,6 +717,24 @@ public abstract class MapBinder<K, V> { } } + static final class ValueProvider<V> implements Provider<V> { + private final Provider<V> delegate; + private final Binding<V> binding; + + ValueProvider(Provider<V> delegate, Binding<V> binding) { + this.delegate = delegate; + this.binding = binding; + } + + @Override public V get() { + return delegate.get(); + } + + public Binding<V> getValueBinding() { + return binding; + } + } + /** * A Provider that Map.Entry that is also a Provider. The key is the entry in the * map this corresponds to and the value is the provider of the user's binding. diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java index b8f0f96f..66a4951f 100644 --- a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java +++ b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java @@ -360,7 +360,9 @@ public abstract class Multibinder<T> { Map<T, Binding<T>> result = new LinkedHashMap<T, Binding<T>>(mapCapacity(bindings.size())); for (Binding<T> binding : bindings) { final T newValue = binding.getProvider().get(); - checkConfiguration(newValue != null, "Set injection failed due to null element"); + checkConfiguration(newValue != null, + "Set injection failed due to null element bound at: %s", + binding.getSource()); Binding<T> duplicateBinding = result.put(newValue, binding); if (!permitDuplicates && duplicateBinding != null) { throw newDuplicateValuesException(result, binding, newValue, duplicateBinding); diff --git a/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java b/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java index 303cf2fe..849993f5 100644 --- a/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java +++ b/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java @@ -611,19 +611,21 @@ public class MapBinderTest extends TestCase { } public void testMapBinderMapForbidsNullValues() { - Injector injector = Guice.createInjector(new AbstractModule() { + Module m = new AbstractModule() { @Override protected void configure() { MapBinder.newMapBinder(binder(), String.class, String.class) .addBinding("null").toProvider(Providers.<String>of(null)); } - }); + }; + Injector injector = Guice.createInjector(m); try { injector.getInstance(Key.get(mapOfString)); fail(); } catch(ProvisionException expected) { assertContains(expected.getMessage(), - "1) Map injection failed due to null value for key \"null\""); + "1) Map injection failed due to null value for key \"null\", bound at: " + + m.getClass().getName() + ".configure("); } } diff --git a/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java b/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java index d0b2ee1a..154779d3 100644 --- a/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java +++ b/extensions/multibindings/test/com/google/inject/multibindings/MultibinderTest.java @@ -102,7 +102,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderAggregatesMultipleModules() { Module abc = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("A"); multibinder.addBinding().toInstance("B"); @@ -110,7 +110,7 @@ public class MultibinderTest extends TestCase { } }; Module de = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("D"); multibinder.addBinding().toInstance("E"); @@ -129,7 +129,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderAggregationForAnnotationInstance() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class, Names.named("abc")); multibinder.addBinding().toInstance("A"); @@ -151,7 +151,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderAggregationForAnnotationType() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class, Abc.class); multibinder.addBinding().toInstance("A"); @@ -173,7 +173,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderWithMultipleAnnotationValueSets() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> abcMultibinder = Multibinder.newSetBinder(binder(), String.class, named("abc")); abcMultibinder.addBinding().toInstance("A"); @@ -204,7 +204,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderWithMultipleAnnotationTypeSets() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> abcMultibinder = Multibinder.newSetBinder(binder(), String.class, Abc.class); abcMultibinder.addBinding().toInstance("A"); @@ -235,7 +235,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderWithMultipleSetTypes() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), String.class) .addBinding().toInstance("A"); Multibinder.newSetBinder(binder(), Integer.class) @@ -254,7 +254,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderWithEmptySet() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), String.class); } }; @@ -268,7 +268,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderSetIsUnmodifiable() { Injector injector = Guice.createInjector(new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), String.class) .addBinding().toInstance("A"); } @@ -284,7 +284,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderSetIsSerializable() throws IOException, ClassNotFoundException { Injector injector = Guice.createInjector(new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), String.class) .addBinding().toInstance("A"); } @@ -310,7 +310,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderSetIsLazy() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), Integer.class) .addBinding().toProvider(new Provider<Integer>() { int nextValue = 1; @@ -331,13 +331,13 @@ public class MultibinderTest extends TestCase { public void testMultibinderSetForbidsDuplicateElements() { Module module1 = new AbstractModule() { - protected void configure() { + @Override protected void configure() { final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toProvider(Providers.of("A")); } }; Module module2 = new AbstractModule() { - protected void configure() { + @Override protected void configure() { final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("A"); } @@ -384,14 +384,14 @@ public class MultibinderTest extends TestCase { } Module module1 = new AbstractModule() { - protected void configure() { + @Override protected void configure() { final Multibinder<ValueType> multibinder = Multibinder.newSetBinder(binder(), ValueType.class); multibinder.addBinding().toProvider(Providers.of(new ValueType(1, 2))); } }; Module module2 = new AbstractModule() { - protected void configure() { + @Override protected void configure() { final Multibinder<ValueType> multibinder = Multibinder.newSetBinder(binder(), ValueType.class); multibinder.addBinding().toInstance(new ValueType(1, 3)); @@ -420,14 +420,14 @@ public class MultibinderTest extends TestCase { public void testMultibinderSetPermitDuplicateElements() { Module ab = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("A"); multibinder.addBinding().toInstance("B"); } }; Module bc = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.permitDuplicates(); multibinder.addBinding().toInstance("B"); @@ -443,7 +443,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderSetPermitDuplicateCallsToPermitDuplicates() { Module ab = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.permitDuplicates(); multibinder.addBinding().toInstance("A"); @@ -451,7 +451,7 @@ public class MultibinderTest extends TestCase { } }; Module bc = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.permitDuplicates(); multibinder.addBinding().toInstance("B"); @@ -466,19 +466,21 @@ public class MultibinderTest extends TestCase { } public void testMultibinderSetForbidsNullElements() { - Injector injector = Guice.createInjector(new AbstractModule() { - protected void configure() { + Module m = new AbstractModule() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), String.class) .addBinding().toProvider(Providers.<String>of(null)); } - }); + }; + Injector injector = Guice.createInjector(m); try { injector.getInstance(Key.get(setOfString)); fail(); } catch(ProvisionException expected) { assertContains(expected.getMessage(), - "1) Set injection failed due to null element"); + "1) Set injection failed due to null element bound at: " + + m.getClass().getName() + ".configure("); } } @@ -502,7 +504,7 @@ public class MultibinderTest extends TestCase { */ public void testMultibinderDependencies() { Injector injector = Guice.createInjector(new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("A"); multibinder.addBinding().to(Key.get(String.class, Names.named("b"))); @@ -526,13 +528,14 @@ public class MultibinderTest extends TestCase { */ public void testMultibinderDependenciesInToolStage() { Injector injector = Guice.createInjector(Stage.TOOL, new AbstractModule() { - protected void configure() { - Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); - multibinder.addBinding().toInstance("A"); - multibinder.addBinding().to(Key.get(String.class, Names.named("b"))); + @Override protected void configure() { + Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); + multibinder.addBinding().toInstance("A"); + multibinder.addBinding().to(Key.get(String.class, Names.named("b"))); - bindConstant().annotatedWith(Names.named("b")).to("B"); - }}); + bindConstant().annotatedWith(Names.named("b")).to("B"); + } + }); Binding<Set<String>> binding = injector.getBinding(new Key<Set<String>>() {}); HasDependencies withDependencies = (HasDependencies) binding; @@ -578,12 +581,12 @@ public class MultibinderTest extends TestCase { public void testBindOrderEqualsIterationOrder() { Injector injector = Guice.createInjector( new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("leonardo"); multibinder.addBinding().toInstance("donatello"); install(new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), String.class) .addBinding().toInstance("michaelangelo"); } @@ -591,7 +594,7 @@ public class MultibinderTest extends TestCase { } }, new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("raphael"); } }); @@ -617,21 +620,21 @@ public class MultibinderTest extends TestCase { */ public void testModuleOverrideAndMultibindings() { Module ab = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("A"); multibinder.addBinding().toInstance("B"); } }; Module cd = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("C"); multibinder.addBinding().toInstance("D"); } }; Module ef = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("E"); multibinder.addBinding().toInstance("F"); @@ -652,7 +655,7 @@ public class MultibinderTest extends TestCase { */ public void testModuleOverrideAndMultibindingsWithPermitDuplicates() { Module abc = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("A"); multibinder.addBinding().toInstance("B"); @@ -661,7 +664,7 @@ public class MultibinderTest extends TestCase { } }; Module cd = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("C"); multibinder.addBinding().toInstance("D"); @@ -669,7 +672,7 @@ public class MultibinderTest extends TestCase { } }; Module ef = new AbstractModule() { - protected void configure() { + @Override protected void configure() { Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toInstance("E"); multibinder.addBinding().toInstance("F"); @@ -1136,7 +1139,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderCanInjectCollectionOfProviders() { Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class); multibinder.addBinding().toProvider(Providers.of("A")); multibinder.addBinding().toProvider(Providers.of("B")); @@ -1159,7 +1162,7 @@ public class MultibinderTest extends TestCase { public void testMultibinderCanInjectCollectionOfProvidersWithAnnotation() { final Annotation ann = Names.named("foo"); Module module = new AbstractModule() { - protected void configure() { + @Override protected void configure() { final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class, ann); multibinder.addBinding().toProvider(Providers.of("A")); |