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
Solved! Go to Solution.
Hi, Jdruwe.
The problem is @Component definition of your InheritedValueMapValueInjector. It should be registered for both interfaces - Injector and StaticInjectAnnotationProcessorFactory. For this, either remove "service" property from @Component (so it will automatically take all the implemented interfaces), either specify both of them.
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
Views
Replies
Total Likes
If I use @optitional instead of the strategy it works yes. I want it to work with the strategy
Views
Replies
Total Likes
Hi, Jdruwe.
The problem is @Component definition of your InheritedValueMapValueInjector. It should be registered for both interfaces - Injector and StaticInjectAnnotationProcessorFactory. For this, either remove "service" property from @Component (so it will automatically take all the implemented interfaces), either specify both of them.
Thanks Alex for the great response!
Views
Replies
Total Likes
Thank you, it works now
Views
Replies
Total Likes
Views
Likes
Replies