5 Replies Latest reply on Feb 13, 2018 11:24 PM by Jdruwe

    AEM 6.3: Custom sling model injector, InjectionStrategy.OPTIONAL not working

    Jdruwe Level 1

      I've written my own custom annotation to find a property on the current resource and to return it. This annotation works fine when the property is available on the resource, things go wrong when it is not found:

       

      Annotation:

       

      @Target({ElementType.FIELD})
      @Retention(RetentionPolicy.RUNTIME)
      @InjectAnnotation
      @Source(InheritedValueMapValueInjector.NAME)
      public @interface InheritedValueMapValue {
      
        String property();
        InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
      }
      
      
      

       

      Injector:

       

      @Component(service = {Injector.class}, property = {
      Constants.SERVICE_RANKING + ":Integer=" + 4300
      })
      public class InheritedValueMapValueInjector extends AbstractInjector implements Injector, StaticInjectAnnotationProcessorFactory {
      
      public static final String NAME = "inherited-value-map-value";
      
      @Override
      public String getName() {
        return NAME;
      }
      
      @Override
      public Object getValue(final Object adaptable, final String name, final Type type, final AnnotatedElement element,
         final DisposalCallbackRegistry callbackRegistry) {
        //CUSTOM LOGIC HERE
      }
      
      @Override
      public InjectAnnotationProcessor2 createAnnotationProcessor(final AnnotatedElement element) {
        InheritedValueMapValue annotation = element.getAnnotation(InheritedValueMapValue.class);
        if (annotation != null) {
          return new InheritedValueAnnotationProcessor(annotation);
        }
        return null;
      }
      
      private static class InheritedValueAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
        private final InheritedValueMapValue annotation;
      
        InheritedValueAnnotationProcessor(final InheritedValueMapValue annotation) {
          this.annotation = annotation;
        }
      
          @Override
          public InjectionStrategy getInjectionStrategy() {
             return annotation.injectionStrategy();
          }
        }
      }
      

       

      Use in sling model:

       

      @InheritedValueMapValue(property = "title", injectionStrategy = InjectionStrategy.OPTIONAL)
      private String titleProperty;
      

       

      This is what I see in my error logging:

       

      Suppressed: org.apache.sling.models.factory.MissingElementException: Could not inject private java.lang.String com.company.platform.component.text.HeadingController.titleProperty
      at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:650)
      ... 223 common frames omitted
      Caused by: org.apache.sling.models.factory.ModelClassException: No injector returned a non-null value!
      at org.apache.sling.models.impl.ModelAdapterFactory.injectElement(ModelAdapterFactory.java:565)
      at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:648)
      

       

      When I replace the strategy by an additional 'org.apache.sling.models.annotations.Optional' annotation it works, but I was wondering why it was not when using 'InjectionStrategy.OPTIONAL'? Thanks in advance!

       

      NOTE: I am using AEM 6.3.1.2 uber-jar