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;
}
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.");
}
}
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();
}
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());
}
}
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;
}
Aggregations