Search in sources :

Example 51 with ConfigurationException

use of com.google.inject.ConfigurationException in project guice by google.

the class BoundFieldModuleTest method testBindingSuperTypeAccessSubType.

public void testBindingSuperTypeAccessSubType() {
    final Integer testValue = 1024;
    Object instance = new Object() {

        @Bind(to = Number.class)
        private Integer anInt = testValue;
    };
    BoundFieldModule module = BoundFieldModule.of(instance);
    Injector injector = Guice.createInjector(module);
    try {
        injector.getInstance(Integer.class);
        fail();
    } catch (ConfigurationException e) {
        assertContains(e.getMessage(), "No injectable constructor for type Integer.");
    }
}
Also used : ConfigurationException(com.google.inject.ConfigurationException) Injector(com.google.inject.Injector)

Example 52 with ConfigurationException

use of com.google.inject.ConfigurationException in project guice by google.

the class InjectionPoint method getInjectionPoints.

/**
 * Returns an ordered, immutable set of injection points for the given type. Members in
 * superclasses come before members in subclasses. Within a class, fields come before methods.
 * Overridden methods are filtered out. The order of fields/methods within a class is consistent
 * but undefined.
 *
 * @param statics true is this method should return static members, false for instance members
 * @param errors used to record errors
 */
private static Set<InjectionPoint> getInjectionPoints(final TypeLiteral<?> type, boolean statics, Errors errors) {
    InjectableMembers injectableMembers = new InjectableMembers();
    OverrideIndex overrideIndex = null;
    List<TypeLiteral<?>> hierarchy = hierarchyFor(type);
    int topIndex = hierarchy.size() - 1;
    for (int i = topIndex; i >= 0; i--) {
        if (overrideIndex != null && i < topIndex) {
            // Knowing the position within the hierarchy helps us make optimizations.
            if (i == 0) {
                overrideIndex.position = Position.BOTTOM;
            } else {
                overrideIndex.position = Position.MIDDLE;
            }
        }
        TypeLiteral<?> current = hierarchy.get(i);
        for (Field field : getDeclaredFields(current)) {
            if (Modifier.isStatic(field.getModifiers()) == statics) {
                Annotation atInject = getAtInject(field);
                if (atInject != null) {
                    InjectableField injectableField = new InjectableField(current, field, atInject);
                    if (injectableField.jsr330 && Modifier.isFinal(field.getModifiers())) {
                        errors.cannotInjectFinalField(field);
                    }
                    injectableMembers.add(injectableField);
                }
            }
        }
        for (Method method : getDeclaredMethods(current)) {
            if (isEligibleForInjection(method, statics)) {
                Annotation atInject = getAtInject(method);
                if (atInject != null) {
                    InjectableMethod injectableMethod = new InjectableMethod(current, method, atInject);
                    if (checkForMisplacedBindingAnnotations(method, errors) || !isValidMethod(injectableMethod, errors)) {
                        if (overrideIndex != null) {
                            boolean removed = overrideIndex.removeIfOverriddenBy(method, false, injectableMethod);
                            if (removed) {
                                logger.log(Level.WARNING, "Method: {0} is not a valid injectable method (" + "because it either has misplaced binding annotations " + "or specifies type parameters) but is overriding a method that is " + "valid. Because it is not valid, the method will not be injected. " + "To fix this, make the method a valid injectable method.", method);
                            }
                        }
                        continue;
                    }
                    if (statics) {
                        injectableMembers.add(injectableMethod);
                    } else {
                        if (overrideIndex == null) {
                            /*
                 * Creating the override index lazily means that the first type in the hierarchy
                 * with injectable methods (not necessarily the top most type) will be treated as
                 * the TOP position and will enjoy the same optimizations (no checks for overridden
                 * methods, etc.).
                 */
                            overrideIndex = new OverrideIndex(injectableMembers);
                        } else {
                            // Forcibly remove the overridden method, otherwise we'll inject
                            // it twice.
                            overrideIndex.removeIfOverriddenBy(method, true, injectableMethod);
                        }
                        overrideIndex.add(injectableMethod);
                    }
                } else {
                    if (overrideIndex != null) {
                        boolean removed = overrideIndex.removeIfOverriddenBy(method, false, null);
                        if (removed) {
                            logger.log(Level.WARNING, "Method: {0} is not annotated with @Inject but " + "is overriding a method that is annotated with @javax.inject.Inject." + "Because it is not annotated with @Inject, the method will not be " + "injected. To fix this, annotate the method with @Inject.", method);
                        }
                    }
                }
            }
        }
    }
    if (injectableMembers.isEmpty()) {
        return Collections.emptySet();
    }
    ImmutableSet.Builder<InjectionPoint> builder = ImmutableSet.builder();
    for (InjectableMember im = injectableMembers.head; im != null; im = im.next) {
        try {
            builder.add(im.toInjectionPoint());
        } catch (ConfigurationException ignorable) {
            if (!im.optional) {
                errors.merge(ignorable.getErrorMessages());
            }
        }
    }
    return builder.build();
}
Also used : Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) Field(java.lang.reflect.Field) TypeLiteral(com.google.inject.TypeLiteral) ImmutableSet(com.google.common.collect.ImmutableSet) ConfigurationException(com.google.inject.ConfigurationException)

Example 53 with ConfigurationException

use of com.google.inject.ConfigurationException in project guice by google.

the class InjectionPoint method forConstructorOf.

/**
 * Returns a new injection point for the injectable constructor of {@code type}.
 *
 * <p>If {@code atInjectRequired} is true, the constructor must be annotated with {@code @Inject}.
 * If {@code atInjectRequired} is false, either a {@code @Inject} annotated constructor or a
 * non-private no arg constructor is required to be defined by the class corresponding to {@code
 * type}.
 *
 * @param type a concrete type with exactly one constructor annotated {@code @Inject}, or a
 *     no-arguments constructor that is not private.
 * @param atInjectRequired whether the constructor must be annotated with {@code Inject}.
 * @throws ConfigurationException if there is no injectable constructor, more than one injectable
 *     constructor, or if parameters of the injectable constructor are malformed, such as a
 *     parameter with multiple binding annotations.
 * @since 5.0
 */
public static InjectionPoint forConstructorOf(TypeLiteral<?> type, boolean atInjectRequired) {
    Class<?> rawType = getRawType(type.getType());
    Errors errors = new Errors(rawType);
    List<Constructor<?>> atInjectConstructors = Arrays.stream(rawType.getDeclaredConstructors()).filter(constructor -> constructor.isAnnotationPresent(Inject.class) || constructor.isAnnotationPresent(javax.inject.Inject.class)).collect(Collectors.toList());
    Constructor<?> injectableConstructor = null;
    atInjectConstructors.stream().filter(constructor -> constructor.isAnnotationPresent(Inject.class)).filter(constructor -> constructor.getAnnotation(Inject.class).optional()).forEach(errors::optionalConstructor);
    if (atInjectConstructors.size() > 1) {
        errors.tooManyConstructors(rawType);
    } else {
        injectableConstructor = Iterables.getOnlyElement(atInjectConstructors, null);
        if (injectableConstructor != null) {
            checkForMisplacedBindingAnnotations(injectableConstructor, errors);
        }
    }
    if (atInjectRequired && injectableConstructor == null) {
        errors.atInjectRequired(type);
    }
    errors.throwConfigurationExceptionIfErrorsExist();
    if (injectableConstructor != null) {
        return new InjectionPoint(type, injectableConstructor);
    }
    // If no annotated constructor is found, look for a no-arg constructor instead.
    try {
        Constructor<?> noArgConstructor = rawType.getDeclaredConstructor();
        // Disallow private constructors on non-private classes (unless they have @Inject)
        if (Modifier.isPrivate(noArgConstructor.getModifiers()) && !Modifier.isPrivate(rawType.getModifiers())) {
            errors.missingConstructor(type);
            throw new ConfigurationException(errors.getMessages());
        }
        checkForMisplacedBindingAnnotations(noArgConstructor, errors);
        return new InjectionPoint(type, noArgConstructor);
    } catch (NoSuchMethodException e) {
        errors.missingConstructor(type);
        throw new ConfigurationException(errors.getMessages());
    }
}
Also used : Iterables(com.google.common.collect.Iterables) Arrays(java.util.Arrays) MoreTypes.getRawType(com.google.inject.internal.MoreTypes.getRawType) Inject(com.google.inject.Inject) Annotations(com.google.inject.internal.Annotations) Key(com.google.inject.Key) HashMap(java.util.HashMap) Constructor(java.lang.reflect.Constructor) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) ErrorsException(com.google.inject.internal.ErrorsException) KotlinSupport(com.google.inject.internal.KotlinSupport) Map(java.util.Map) Method(java.lang.reflect.Method) DeclaredMembers(com.google.inject.internal.DeclaredMembers) Nullability(com.google.inject.internal.Nullability) ImmutableSet(com.google.common.collect.ImmutableSet) ObjectArrays(com.google.common.collect.ObjectArrays) Iterator(java.util.Iterator) Classes(com.google.inject.internal.util.Classes) Predicate(java.util.function.Predicate) Member(java.lang.reflect.Member) AnnotatedType(java.lang.reflect.AnnotatedType) ConfigurationException(com.google.inject.ConfigurationException) Set(java.util.Set) Field(java.lang.reflect.Field) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) Errors(com.google.inject.internal.Errors) List(java.util.List) Modifier(java.lang.reflect.Modifier) Annotation(java.lang.annotation.Annotation) TypeLiteral(com.google.inject.TypeLiteral) Collections(java.util.Collections) AnnotatedElement(java.lang.reflect.AnnotatedElement) Inject(com.google.inject.Inject) Errors(com.google.inject.internal.Errors) ConfigurationException(com.google.inject.ConfigurationException) Constructor(java.lang.reflect.Constructor)

Example 54 with ConfigurationException

use of com.google.inject.ConfigurationException in project guice by google.

the class InjectionPoint method forInstanceMethodsAndFields.

/**
 * Returns all instance method and field injection points on {@code type}.
 *
 * @return a possibly empty set of injection points. The set has a specified iteration order. All
 *     fields are returned and then all methods. Within the fields, supertype fields are returned
 *     before subtype fields. Similarly, supertype methods are returned before subtype methods.
 * @throws ConfigurationException if there is a malformed injection point on {@code type}, such as
 *     a field with multiple binding annotations. The exception's {@link
 *     ConfigurationException#getPartialValue() partial value} is a {@code Set<InjectionPoint>} of
 *     the valid injection points.
 */
public static Set<InjectionPoint> forInstanceMethodsAndFields(TypeLiteral<?> type) {
    Errors errors = new Errors();
    Set<InjectionPoint> result = getInjectionPoints(type, false, errors);
    if (errors.hasErrors()) {
        throw new ConfigurationException(errors.getMessages()).withPartialValue(result);
    }
    return result;
}
Also used : Errors(com.google.inject.internal.Errors) ConfigurationException(com.google.inject.ConfigurationException)

Example 55 with ConfigurationException

use of com.google.inject.ConfigurationException in project guice by google.

the class ModuleRewriterTest method testRewriteBindings.

public void testRewriteBindings() {
    // create a module the binds String.class and CharSequence.class
    Module module = new AbstractModule() {

        @Override
        protected void configure() {
            bind(String.class).toInstance("Pizza");
            bind(CharSequence.class).toInstance("Wine");
        }
    };
    // record the elements from that module
    List<Element> elements = Elements.getElements(module);
    // create a rewriter that rewrites the binding to 'Wine' with a binding to 'Beer'
    List<Element> rewritten = Lists.newArrayList();
    for (Element element : elements) {
        element = element.acceptVisitor(new DefaultElementVisitor<Element>() {

            @Override
            public <T> Element visit(Binding<T> binding) {
                T target = binding.acceptTargetVisitor(Elements.<T>getInstanceVisitor());
                if ("Wine".equals(target)) {
                    return null;
                } else {
                    return binding;
                }
            }
        });
        if (element != null) {
            rewritten.add(element);
        }
    }
    // create a module from the original list of elements and the rewriter
    Module rewrittenModule = Elements.getModule(rewritten);
    // the wine binding is dropped
    Injector injector = Guice.createInjector(rewrittenModule);
    try {
        injector.getInstance(CharSequence.class);
        fail();
    } catch (ConfigurationException expected) {
    }
}
Also used : Binding(com.google.inject.Binding) ConfigurationException(com.google.inject.ConfigurationException) Injector(com.google.inject.Injector) Module(com.google.inject.Module) AbstractModule(com.google.inject.AbstractModule) AbstractModule(com.google.inject.AbstractModule)

Aggregations

ConfigurationException (com.google.inject.ConfigurationException)62 Injector (com.google.inject.Injector)16 Errors (com.google.inject.internal.Errors)13 InjectionPoint (com.google.inject.spi.InjectionPoint)8 Method (java.lang.reflect.Method)7 AbstractModule (com.google.inject.AbstractModule)5 Inject (com.google.inject.Inject)5 ErrorsException (com.google.inject.internal.ErrorsException)5 Annotation (java.lang.annotation.Annotation)5 TypeLiteral (com.google.inject.TypeLiteral)4 Map (java.util.Map)4 ImmutableMap (com.google.common.collect.ImmutableMap)3 GuiceUtil (com.google.gwt.inject.rebind.util.GuiceUtil)3 Module (com.google.inject.Module)3 Message (com.google.inject.spi.Message)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Test (org.junit.Test)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Binding (com.google.inject.Binding)2