Search in sources :

Example 41 with ConfigurationException

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

the class BindingBuilder method toConstructor.

@Override
public <S extends T> ScopedBindingBuilder toConstructor(Constructor<S> constructor, TypeLiteral<? extends S> type) {
    checkNotNull(constructor, "constructor");
    checkNotNull(type, "type");
    checkNotTargetted();
    BindingImpl<T> base = getBinding();
    Set<InjectionPoint> injectionPoints;
    try {
        injectionPoints = InjectionPoint.forInstanceMethodsAndFields(type);
    } catch (ConfigurationException e) {
        copyErrorsToBinder(e);
        injectionPoints = e.getPartialValue();
    }
    try {
        InjectionPoint constructorPoint = InjectionPoint.forConstructor(constructor, type);
        setBinding(new ConstructorBindingImpl<T>(base.getKey(), base.getSource(), base.getScoping(), constructorPoint, injectionPoints));
    } catch (ConfigurationException e) {
        copyErrorsToBinder(e);
    }
    return this;
}
Also used : InjectionPoint(com.google.inject.spi.InjectionPoint) ConfigurationException(com.google.inject.ConfigurationException)

Example 42 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 43 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 44 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 45 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)

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