Expand my Community achievements bar.

SOLVED

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

Avatar

Level 5

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

1 Accepted Solution

Avatar

Correct answer by
Level 2

Hi,

View solution in original post

5 Replies

Avatar

Level 10

To clarify - it works when you use - org.apache.sling.models.annotations.Optional.

To those reading this thread and want to know  how to use Align Model Injector with AEM -- see this article on the subject -- Creating a Sling Model Injector for Adobe Experience Manager

Avatar

Level 5

If I use @optitional instead of the strategy it works yes. I want it to work with the strategy

Avatar

Correct answer by
Level 2

Hi,

Avatar

Level 10

Thanks Alex for the great response!