public void testNullability() throws Exception { Module module = new AbstractModule() { @Override protected void configure() { bind(String.class).toProvider(Providers.<String>of(null)); } @SuppressWarnings("unused") @Provides Integer fail(String foo) { return 1; } @SuppressWarnings("unused") @Provides Long succeed(@Nullable String foo) { return 2L; } }; Injector injector = Guice.createInjector(module); InjectionPoint fooPoint = InjectionPoint.forMethod( module.getClass().getDeclaredMethod("fail", String.class), TypeLiteral.get(module.getClass())); Dependency<?> fooDependency = Iterables.getOnlyElement(fooPoint.getDependencies()); runNullableTest(injector, fooDependency, module); injector.getInstance(Long.class); }
public void testProviderMethodDependenciesAreExposed() throws Exception { Module module = new AbstractModule() { @Override protected void configure() { bind(Integer.class).toInstance(50); bindConstant().annotatedWith(Names.named("units")).to("Kg"); } @Provides @Named("weight") String provideWeight(Integer count, @Named("units") String units) { return count + units; } }; Injector injector = Guice.createInjector(module); ProviderInstanceBinding<?> binding = (ProviderInstanceBinding<?>) injector.getBinding(Key.get(String.class, Names.named("weight"))); Method method = module.getClass().getDeclaredMethod("provideWeight", Integer.class, String.class); InjectionPoint point = new InjectionPoint(TypeLiteral.get(module.getClass()), method, false); assertEquals( ImmutableSet.<Dependency<?>>of( new Dependency<Integer>(point, Key.get(Integer.class), false, 0), new Dependency<String>(point, Key.get(String.class, Names.named("units")), false, 1)), binding.getDependencies()); }
private boolean evaluateConditions(Logger LOG, Injector injector, Module module) throws Exception { LOG.info("Evaluating module {}", module.getClass().getName()); // The class may have multiple Conditional annotations for (Annotation annot : module.getClass().getAnnotations()) { Conditional conditional = annot.annotationType().getAnnotation(Conditional.class); if (conditional != null) { // A Conditional may have a list of multiple Conditions for (Class<? extends Condition> condition : conditional.value()) { try { // Construct the condition using Guice so that anything may be injected into // the condition Condition c = injector.getInstance(condition); // Look for method signature : boolean check(T annot) // where T is the annotation type. Note that the same checker will be used // for all conditions of the same annotation type. try { Method check = condition.getDeclaredMethod("check", annot.annotationType()); if (!(boolean) check.invoke(c, annot)) { LOG.info(" - {}", formatConditional(annot)); return false; } } // If not found, look for method signature // boolean check(); catch (NoSuchMethodException e) { Method check = condition.getDeclaredMethod("check"); if (!(boolean) check.invoke(c)) { LOG.info(" - {}", formatConditional(annot)); return false; } } LOG.info(" + {}", formatConditional(annot)); } catch (Exception e) { LOG.info(" - {}", formatConditional(annot)); throw new Exception( "Failed to check condition '" + condition + "' on module '" + module.getClass() + "'"); } } } } return true; }
/** * Please do not invoke this method unless you know what you are doing. This initializes Guice and * does it once only so that synchronization is not used. This is called by the JCatapultFilter in * its constructor and should cover all cases. */ public static void initialize() { logger.info("Initializing JCatapult's Guice support"); Set<Class<? extends Module>> classes = new HashSet<Class<? extends Module>>(); if (loadFromClasspath) { addFromClasspath(classes); } addFromConfiguration(classes); List<Module> modules = new ArrayList<Module>(); for (Class<? extends Module> moduleClass : classes) { try { modules.add(moduleClass.newInstance()); } catch (Exception e) { throw new RuntimeException(e); } } if (GuiceContainer.guiceModules != null) { for (Module module : GuiceContainer.guiceModules) { if (classes.contains(module.getClass())) { continue; } modules.add(module); } } GuiceContainer.injector = Guice.createInjector(modules); }
private void validateNullableFails(Injector injector, Module module) { try { injector.getInstance(Integer.class); fail(); } catch (ProvisionException expected) { assertContains( expected.getMessage(), "1) null returned by binding at " + module.getClass().getName() + ".configure(", "but the 1st parameter of " + module.getClass().getName() + ".fail(", "is not @Nullable", "while locating java.lang.String", "for the 1st parameter of " + module.getClass().getName() + ".fail(", "while locating java.lang.Integer"); assertEquals(1, expected.getErrorMessages().size()); } }
public void testSpi() throws Exception { Module m1 = new AbstractModule() { @Override protected void configure() {} @Provides @Named("foo") String provideFoo(Integer dep) { return "foo"; } }; Module m2 = new AbstractModule() { @Override protected void configure() {} @Provides Integer provideInt(@Named("foo") String dep) { return 42; } }; Injector injector = Guice.createInjector(m1, m2); Binding<String> stringBinding = injector.getBinding(Key.get(String.class, Names.named("foo"))); ProvidesMethodBinding<String> stringMethod = stringBinding.acceptTargetVisitor(new BindingCapturer<String>()); assertEquals(m1, stringMethod.getEnclosingInstance()); assertEquals( m1.getClass().getDeclaredMethod("provideFoo", Integer.class), stringMethod.getMethod()); assertEquals( ((HasDependencies) stringBinding).getDependencies(), stringMethod.getDependencies()); assertEquals(Key.get(String.class, Names.named("foo")), stringMethod.getKey()); Binding<Integer> intBinding = injector.getBinding(Integer.class); ProvidesMethodBinding<Integer> intMethod = intBinding.acceptTargetVisitor(new BindingCapturer<Integer>()); assertEquals(m2, intMethod.getEnclosingInstance()); assertEquals( m2.getClass().getDeclaredMethod("provideInt", String.class), intMethod.getMethod()); assertEquals(((HasDependencies) intBinding).getDependencies(), intMethod.getDependencies()); assertEquals(Key.get(Integer.class), intMethod.getKey()); }
public static Module loadFromClasspath(Class<? extends Module> moduleType) { List<Module> runtime = new LinkedList<Module>(); List<Module> overrides = new LinkedList<Module>(); for (Module module : ServiceLoader.load(moduleType)) { if (module.getClass().isAnnotationPresent(OverrideModule.class)) overrides.add(module); else runtime.add(module); } return overrides.isEmpty() ? Modules.combine(runtime) : Modules.override(runtime).with(overrides); }
private Module create( final Logger LOG, final LifecycleManager manager, final Collection<Module> loadedModules, final List<Module> rootModules, final boolean isBootstrap, final Module bootstrapModule) throws Exception { LOG.info("Creating {} injector", isBootstrap ? "bootstrap" : "main"); // Populate all the bootstrap state from the main module final List<Element> elements = Elements.getElements(Stage.DEVELOPMENT, rootModules); final Set<Key<?>> keys = ElementsEx.getAllInjectionKeys(elements); final List<String> moduleNames = ElementsEx.getAllSourceModules(elements); final Injector injector = Guice.createInjector( stage, new LifecycleModule(), new AbstractModule() { @Override protected void configure() { bind(LifecycleManager.class).toInstance(manager); requestInjection(manager); } }, Modules.override( new DefaultModule() { @Provides public AutoContext getContext() { return new AutoContext() { @Override public boolean hasProfile(String profile) { return profiles.contains(profile); } @Override public boolean hasModule(String className) { return moduleNames.contains(className); } @Override public boolean hasBinding(Key<?> key) { return keys.contains(key); } }; } }) .with(bootstrapModule)); PropertySource propertySource = injector.getInstance(PropertySource.class); // Iterate through all loaded modules and filter out any modules that // have failed the condition check. Also, keep track of any override modules // for already installed modules. final List<Module> overrideModules = new ArrayList<>(); final List<Module> moreModules = new ArrayList<>(); for (Module module : loadedModules) { if (!isEnabled(propertySource, module.getClass().getName())) { LOG.info("Ignoring module {}", module.getClass().getName()); continue; } Bootstrap bs = module.getClass().getAnnotation(Bootstrap.class); if (isBootstrap == (bs != null) && evaluateConditions(LOG, injector, module)) { OverrideModule override = module.getClass().getAnnotation(OverrideModule.class); if (override != null) { if (moduleNames.contains(override.value().getName())) { LOG.info(" Adding override module {}", module.getClass().getSimpleName()); overrideModules.add(module); } } else { LOG.info(" Adding conditional module {}", module.getClass().getSimpleName()); moreModules.add(module); } } } final List<Module> extModules = new ArrayList<>(); List<Binding<ModuleProvider>> moduleProviders = injector.findBindingsByType(TypeLiteral.get(ModuleProvider.class)); for (Binding<ModuleProvider> binding : moduleProviders) { Module module = binding.getProvider().get().get(); LOG.debug("Adding exposed bootstrap module {}", module.getClass().getName()); extModules.add(module); } LOG.debug("Root Modules : " + rootModules); LOG.debug("More Modules : " + moreModules); LOG.debug("Override Modules : " + overrideModules); LOG.debug("Ext Modules : " + extModules); LOG.debug("Created {} injector", isBootstrap ? "bootstrap" : "main"); Module m = Modules.override( new AbstractModule() { @Override protected void configure() { install(Modules.combine(rootModules)); install(Modules.combine(moreModules)); } }) .with(Modules.override(overrideModules).with(Modules.combine(extModules))); return m; }