use of io.micronaut.context.exceptions.DependencyInjectionException in project micronaut-core by micronaut-projects.
the class AbstractInitializableBeanDefinition method resolveValue.
private Object resolveValue(BeanResolutionContext resolutionContext, BeanContext context, AnnotationMetadata parentAnnotationMetadata, Argument<?> argument, Qualifier qualifier) {
if (!(context instanceof PropertyResolver)) {
throw new DependencyInjectionException(resolutionContext, "@Value requires a BeanContext that implements PropertyResolver");
}
String valueAnnVal = argument.getAnnotationMetadata().stringValue(Value.class).orElse(null);
Argument<?> argumentType;
boolean isCollection = false;
final boolean wrapperType = argument.isWrapperType();
final Class<?> argumentJavaType = argument.getType();
if (Collection.class.isAssignableFrom(argumentJavaType)) {
argumentType = argument.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT);
isCollection = true;
} else if (wrapperType) {
argumentType = argument.getWrappedType();
} else {
argumentType = argument;
}
if (isInnerConfiguration(argumentType.getType())) {
qualifier = qualifier == null ? resolveQualifierWithInnerConfiguration(resolutionContext, argument, true) : qualifier;
if (isCollection) {
Collection beans = ((DefaultBeanContext) context).getBeansOfType(resolutionContext, argumentType, qualifier);
return coerceCollectionToCorrectType((Class) argumentJavaType, beans, resolutionContext, argument);
} else {
return ((DefaultBeanContext) context).getBean(resolutionContext, argumentType, qualifier);
}
} else {
String valString = resolvePropertyValueName(resolutionContext, parentAnnotationMetadata, argument.getAnnotationMetadata(), valueAnnVal);
ArgumentConversionContext conversionContext = wrapperType ? ConversionContext.of(argumentType) : ConversionContext.of(argument);
Optional value = resolveValue((ApplicationContext) context, conversionContext, valueAnnVal != null, valString);
if (argument.isOptional()) {
if (!value.isPresent()) {
return value;
} else {
Object convertedOptional = value.get();
if (convertedOptional instanceof Optional) {
return convertedOptional;
} else {
return value;
}
}
} else {
if (wrapperType) {
final Object v = value.orElse(null);
if (OptionalInt.class == argumentJavaType) {
return v instanceof Integer ? OptionalInt.of((Integer) v) : OptionalInt.empty();
} else if (OptionalLong.class == argumentJavaType) {
return v instanceof Long ? OptionalLong.of((Long) v) : OptionalLong.empty();
} else if (OptionalDouble.class == argumentJavaType) {
return v instanceof Double ? OptionalDouble.of((Double) v) : OptionalDouble.empty();
}
}
if (value.isPresent()) {
return value.get();
} else {
if (argument.isDeclaredNullable()) {
return null;
}
return argument.getAnnotationMetadata().getValue(Bindable.class, "defaultValue", argument).orElseThrow(() -> DependencyInjectionException.missingProperty(resolutionContext, conversionContext, valString));
}
}
}
}
use of io.micronaut.context.exceptions.DependencyInjectionException in project micronaut-core by micronaut-projects.
the class AbstractInitializableBeanDefinition method getValueForConstructorArgument.
/**
* Obtains a value for a bean definition for a constructor at the given index
* <p>
* Warning: this method is used by internal generated code and should not be called by user code.
*
* @param resolutionContext The resolution context
* @param context The context
* @param argIndex The argument index
* @param qualifier The qualifier
* @return The resolved bean
*/
@Internal
@UsedByGeneratedCode
@Deprecated
protected final Object getValueForConstructorArgument(BeanResolutionContext resolutionContext, BeanContext context, int argIndex, Qualifier qualifier) {
MethodReference constructorRef = (MethodReference) constructor;
Argument<?> argument = constructorRef.arguments[argIndex];
try (BeanResolutionContext.Path ignored = resolutionContext.getPath().pushConstructorResolve(this, argument)) {
try {
Object result = resolveValue(resolutionContext, context, constructorRef.annotationMetadata, argument, qualifier);
if (this instanceof ValidatedBeanDefinition) {
((ValidatedBeanDefinition) this).validateBeanArgument(resolutionContext, getConstructor(), argument, argIndex, result);
}
return result;
} catch (NoSuchBeanException | BeanInstantiationException e) {
throw new DependencyInjectionException(resolutionContext, argument, e);
}
}
}
use of io.micronaut.context.exceptions.DependencyInjectionException in project micronaut-core by micronaut-projects.
the class AbstractInitializableBeanDefinition method getPropertyValueForConstructorArgument.
/**
* Obtains a property value for a bean definition for a constructor at the given index
* <p>
* Warning: this method is used by internal generated code and should not be called by user code.
*
* @param resolutionContext The resolution context
* @param context The context
* @param argIndex The argument index
* @param propertyValue The property value
* @param cliProperty The cli property
* @return The resolved bean
*/
@Internal
@UsedByGeneratedCode
protected final Object getPropertyValueForConstructorArgument(BeanResolutionContext resolutionContext, BeanContext context, int argIndex, String propertyValue, String cliProperty) {
MethodReference constructorRef = (MethodReference) constructor;
Argument<?> argument = constructorRef.arguments[argIndex];
try (BeanResolutionContext.Path ignored = resolutionContext.getPath().pushConstructorResolve(this, argument)) {
try {
Object result = resolvePropertyValue(resolutionContext, context, argument, propertyValue, cliProperty, false);
if (this instanceof ValidatedBeanDefinition) {
((ValidatedBeanDefinition) this).validateBeanArgument(resolutionContext, getConstructor(), argument, argIndex, result);
}
return result;
} catch (NoSuchBeanException | BeanInstantiationException e) {
throw new DependencyInjectionException(resolutionContext, argument, e);
}
}
}
use of io.micronaut.context.exceptions.DependencyInjectionException in project micronaut-core by micronaut-projects.
the class VehicleSpec method testStartWithInvalidValue.
@Test
public void testStartWithInvalidValue() {
try (ApplicationContext applicationContext = ApplicationContext.run(CollectionUtils.mapOf("my.engine.cylinders", "-10", "my.engine.crank-shaft.rod-length", "7.0"))) {
applicationContext.getBean(Vehicle.class);
fail("Should have failed with a validation error");
} catch (DependencyInjectionException e) {
assertTrue(e.getCause().getMessage().contains("EngineConfig.cylinders - must be greater than or equal to 1"));
}
}
use of io.micronaut.context.exceptions.DependencyInjectionException in project micronaut-core by micronaut-projects.
the class DefaultBeanContext method doCreateBean.
/**
* Execution the creation of a bean. The returned value can be null if a
* factory method returned null.
*
* @param resolutionContext The {@link BeanResolutionContext}
* @param beanDefinition The {@link BeanDefinition}
* @param qualifier The {@link Qualifier}
* @param qualifierBeanType The bean type used in the qualifier
* @param isSingleton Whether the bean is a singleton
* @param argumentValues Any argument values passed to create the bean
* @param <T> The bean generic type
* @return The created bean
*/
@Nullable
protected <T> T doCreateBean(@NonNull BeanResolutionContext resolutionContext, @NonNull BeanDefinition<T> beanDefinition, @Nullable Qualifier<T> qualifier, @Nullable Argument<T> qualifierBeanType, boolean isSingleton, @Nullable Map<String, Object> argumentValues) {
if (argumentValues == null) {
argumentValues = Collections.emptyMap();
}
Qualifier<T> declaredQualifier = beanDefinition.getDeclaredQualifier();
Class<T> beanType = beanDefinition.getBeanType();
if (isSingleton) {
BeanRegistration<T> beanRegistration = singletonObjects.get(new BeanKey<>(beanDefinition, declaredQualifier));
final Class<T> beanClass = qualifierBeanType.getType();
if (beanRegistration != null) {
if (qualifier == null || qualifier.reduce(beanClass, Stream.of(beanRegistration.beanDefinition)).findFirst().isPresent()) {
return beanRegistration.bean;
}
} else if (qualifier != null) {
beanRegistration = singletonObjects.get(new BeanKey<>(beanDefinition, null));
if (beanRegistration != null && qualifier.reduce(beanClass, Stream.of(beanRegistration.beanDefinition)).findFirst().isPresent()) {
return beanRegistration.bean;
}
}
}
T bean;
if (beanDefinition instanceof BeanFactory) {
BeanFactory<T> beanFactory = (BeanFactory<T>) beanDefinition;
try {
if (beanFactory instanceof ParametrizedBeanFactory) {
ParametrizedBeanFactory<T> parametrizedBeanFactory = (ParametrizedBeanFactory<T>) beanFactory;
Argument<?>[] requiredArguments = parametrizedBeanFactory.getRequiredArguments();
Map<String, Object> convertedValues = new LinkedHashMap<>(argumentValues);
for (Argument<?> requiredArgument : requiredArguments) {
String argumentName = requiredArgument.getName();
Object val = argumentValues.get(argumentName);
if (val == null && !requiredArgument.isDeclaredNullable()) {
throw new BeanInstantiationException(resolutionContext, "Missing bean argument [" + requiredArgument + "] for type: " + beanType.getName() + ". Required arguments: " + ArrayUtils.toString(requiredArguments));
}
Object convertedValue = null;
if (val != null) {
if (requiredArgument.getType().isInstance(val)) {
convertedValue = val;
} else {
convertedValue = ConversionService.SHARED.convert(val, requiredArgument).orElseThrow(() -> new BeanInstantiationException(resolutionContext, "Invalid bean argument [" + requiredArgument + "]. Cannot convert object [" + val + "] to required type: " + requiredArgument.getType()));
}
}
convertedValues.put(argumentName, convertedValue);
}
bean = parametrizedBeanFactory.build(resolutionContext, this, beanDefinition, convertedValues);
} else {
boolean propagateQualifier = beanDefinition.isProxy() && declaredQualifier instanceof Named;
if (propagateQualifier) {
resolutionContext.setAttribute(BeanDefinition.NAMED_ATTRIBUTE, ((Named) declaredQualifier).getName());
}
resolutionContext.setCurrentQualifier(declaredQualifier != null ? declaredQualifier : qualifier);
try {
bean = beanFactory.build(resolutionContext, this, beanDefinition);
} finally {
resolutionContext.setCurrentQualifier(null);
if (propagateQualifier) {
resolutionContext.removeAttribute(BeanDefinition.NAMED_ATTRIBUTE);
}
}
if (bean == null) {
throw new BeanInstantiationException(resolutionContext, "Bean Factory [" + beanFactory + "] returned null");
} else {
if (bean instanceof Qualified) {
((Qualified) bean).$withBeanQualifier(declaredQualifier);
}
}
}
} catch (Throwable e) {
if (e instanceof DependencyInjectionException) {
throw e;
}
if (e instanceof DisabledBeanException) {
throw e;
}
if (e instanceof BeanInstantiationException) {
throw e;
} else {
if (!resolutionContext.getPath().isEmpty()) {
throw new BeanInstantiationException(resolutionContext, e);
} else {
throw new BeanInstantiationException(beanDefinition, e);
}
}
}
} else {
ConstructorInjectionPoint<T> constructor = beanDefinition.getConstructor();
Argument<?>[] requiredConstructorArguments = constructor.getArguments();
if (requiredConstructorArguments.length == 0) {
bean = constructor.invoke();
} else {
Object[] constructorArgs = new Object[requiredConstructorArguments.length];
for (int i = 0; i < requiredConstructorArguments.length; i++) {
Class<?> argument = requiredConstructorArguments[i].getType();
constructorArgs[i] = getBean(resolutionContext, argument);
}
bean = constructor.invoke(constructorArgs);
}
inject(resolutionContext, null, bean);
}
if (bean != null) {
Qualifier<T> finalQualifier = qualifier != null ? qualifier : declaredQualifier;
if (!(bean instanceof BeanCreatedEventListener) && CollectionUtils.isNotEmpty(beanCreationEventListeners)) {
for (Map.Entry<Class, List<BeanCreatedEventListener>> entry : beanCreationEventListeners) {
if (entry.getKey().isAssignableFrom(beanType)) {
BeanKey<T> beanKey = new BeanKey<>(beanDefinition, finalQualifier);
for (BeanCreatedEventListener<?> listener : entry.getValue()) {
bean = (T) listener.onCreated(new BeanCreatedEvent(this, beanDefinition, beanKey, bean));
if (bean == null) {
throw new BeanInstantiationException(resolutionContext, "Listener [" + listener + "] returned null from onCreated event");
}
}
}
}
}
if (beanDefinition instanceof ValidatedBeanDefinition) {
bean = ((ValidatedBeanDefinition<T>) beanDefinition).validate(resolutionContext, bean);
}
if (LOG_LIFECYCLE.isDebugEnabled()) {
LOG_LIFECYCLE.debug("Created bean [{}] from definition [{}] with qualifier [{}]", bean, beanDefinition, finalQualifier);
}
}
return bean;
}
Aggregations