Search in sources :

Example 6 with DependencyInjectionException

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));
            }
        }
    }
}
Also used : Optional(java.util.Optional) Bindable(io.micronaut.core.bind.annotation.Bindable) PropertyResolver(io.micronaut.core.value.PropertyResolver) OptionalDouble(java.util.OptionalDouble) DependencyInjectionException(io.micronaut.context.exceptions.DependencyInjectionException) ArgumentConversionContext(io.micronaut.core.convert.ArgumentConversionContext) Value(io.micronaut.context.annotation.Value) OptionalLong(java.util.OptionalLong) Collection(java.util.Collection) OptionalLong(java.util.OptionalLong)

Example 7 with DependencyInjectionException

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);
        }
    }
}
Also used : DependencyInjectionException(io.micronaut.context.exceptions.DependencyInjectionException) NoSuchBeanException(io.micronaut.context.exceptions.NoSuchBeanException) BeanInstantiationException(io.micronaut.context.exceptions.BeanInstantiationException) ValidatedBeanDefinition(io.micronaut.inject.ValidatedBeanDefinition) Internal(io.micronaut.core.annotation.Internal) UsedByGeneratedCode(io.micronaut.core.annotation.UsedByGeneratedCode)

Example 8 with DependencyInjectionException

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);
        }
    }
}
Also used : DependencyInjectionException(io.micronaut.context.exceptions.DependencyInjectionException) NoSuchBeanException(io.micronaut.context.exceptions.NoSuchBeanException) BeanInstantiationException(io.micronaut.context.exceptions.BeanInstantiationException) ValidatedBeanDefinition(io.micronaut.inject.ValidatedBeanDefinition) Internal(io.micronaut.core.annotation.Internal) UsedByGeneratedCode(io.micronaut.core.annotation.UsedByGeneratedCode)

Example 9 with DependencyInjectionException

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"));
    }
}
Also used : DependencyInjectionException(io.micronaut.context.exceptions.DependencyInjectionException) ApplicationContext(io.micronaut.context.ApplicationContext) Test(org.junit.Test)

Example 10 with DependencyInjectionException

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;
}
Also used : Argument(io.micronaut.core.type.Argument) BeanCreatedEvent(io.micronaut.context.event.BeanCreatedEvent) LinkedHashMap(java.util.LinkedHashMap) ConcurrentLinkedHashMap(io.micronaut.core.util.clhm.ConcurrentLinkedHashMap) DependencyInjectionException(io.micronaut.context.exceptions.DependencyInjectionException) BeanFactory(io.micronaut.inject.BeanFactory) ParametrizedBeanFactory(io.micronaut.inject.ParametrizedBeanFactory) ParametrizedBeanFactory(io.micronaut.inject.ParametrizedBeanFactory) ArrayList(java.util.ArrayList) List(java.util.List) Named(io.micronaut.core.naming.Named) BeanInstantiationException(io.micronaut.context.exceptions.BeanInstantiationException) Qualified(io.micronaut.inject.qualifiers.Qualified) ValidatedBeanDefinition(io.micronaut.inject.ValidatedBeanDefinition) DisabledBeanException(io.micronaut.context.exceptions.DisabledBeanException) FieldInjectionPoint(io.micronaut.inject.FieldInjectionPoint) ConstructorInjectionPoint(io.micronaut.inject.ConstructorInjectionPoint) InjectionPoint(io.micronaut.inject.InjectionPoint) MethodInjectionPoint(io.micronaut.inject.MethodInjectionPoint) BeanCreatedEventListener(io.micronaut.context.event.BeanCreatedEventListener) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentLinkedHashMap(io.micronaut.core.util.clhm.ConcurrentLinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Nullable(io.micronaut.core.annotation.Nullable)

Aggregations

DependencyInjectionException (io.micronaut.context.exceptions.DependencyInjectionException)11 NoSuchBeanException (io.micronaut.context.exceptions.NoSuchBeanException)5 Internal (io.micronaut.core.annotation.Internal)5 ValidatedBeanDefinition (io.micronaut.inject.ValidatedBeanDefinition)5 BeanInstantiationException (io.micronaut.context.exceptions.BeanInstantiationException)4 BeanContextException (io.micronaut.context.exceptions.BeanContextException)3 UsedByGeneratedCode (io.micronaut.core.annotation.UsedByGeneratedCode)3 Collection (java.util.Collection)3 Argument (io.micronaut.core.type.Argument)2 ApplicationContext (io.micronaut.context.ApplicationContext)1 Value (io.micronaut.context.annotation.Value)1 BeanCreatedEvent (io.micronaut.context.event.BeanCreatedEvent)1 BeanCreatedEventListener (io.micronaut.context.event.BeanCreatedEventListener)1 DisabledBeanException (io.micronaut.context.exceptions.DisabledBeanException)1 NonUniqueBeanException (io.micronaut.context.exceptions.NonUniqueBeanException)1 Nullable (io.micronaut.core.annotation.Nullable)1 Bindable (io.micronaut.core.bind.annotation.Bindable)1 ArgumentConversionContext (io.micronaut.core.convert.ArgumentConversionContext)1 Named (io.micronaut.core.naming.Named)1 DefaultArgument (io.micronaut.core.type.DefaultArgument)1