All AEM as a Cloud Service skills: component development, Workflow model design, development, triggering, launchers, debugging, and triaging, Dispatcher config authoring, advisory, incident response, performance tuning, and security hardening, Rapid Development Environment (RDE) deployment, log inspection, snapshots, and troubleshooting via `aio aem rde`, Jackrabbit Oak query/index tuning (property, Lucene index definitions), and extracting/inventorying JCR queries (XPath, SQL2, QueryBuilder) across a codebase.
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Part of the best-practices skill. Read this module when converting components; do not duplicate these steps inside scheduler, replication, event, or asset pattern files.
Explicit guideline: AEM as a Cloud Service expects OSGi Declarative Services with org.osgi.service.component.annotations (and metatype where configuration applies). Felix SCR (org.apache.felix.scr.annotations) is legacy.
org.apache.felix.scr.annotations.*scr processing if present; ensure bnd-maven-plugin or equivalent declares DS component metadata.org.osgi:org.osgi.service.component.annotations and org.osgi:org.osgi.service.metatype.annotations (aligned with AEM SDK / Cloud Service BOM).Remove:
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;Add DS imports as needed:
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;@Component and @ServiceFelix SCR often combined @Component + @Service. OSGi DS uses a single @Component with service = { ... }.
// BEFORE (Felix SCR)
@Component(immediate = true, metatype = true, label = "...", description = "...")
@Service(value = MyService.class)
public class MyComponent implements MyService { }
// AFTER (OSGi DS)
@Component(service = MyService.class, immediate = true)
public class MyComponent implements MyService { }For multiple service interfaces:
@Component(service = { Runnable.class, MyApi.class })@Reference// BEFORE
@Reference
private SomeService someService;
@Reference(cardinality = ReferenceCardinality.OPTIONAL)
private OptionalService optional;
// AFTER
@Reference
private SomeService someService;
@Reference(cardinality = ReferenceCardinality.OPTIONAL)
private OptionalService optional;Use org.osgi.service.component.annotations.Reference and ReferenceCardinality / ReferencePolicy from the OSGi package, not Felix.
Targeted references:
@Reference(target = "(name=my-agent)")
private DistributionAgent agent;@Activate / @Deactivate / @Modified signaturesPrefer typed configuration with @Designate + OCD instead of Map<String, Object>.
// BEFORE (Felix SCR)
@Activate
protected void activate(Map<String, Object> config) {
String x = PropertiesUtil.toString(config.get("x"), "default");
}
// AFTER (OSGi DS + metatype)
@Activate
protected void activate(MyConfig config) {
String x = config.x();
}
@ObjectClassDefinition(name = "My Component")
public @interface MyConfig {
@AttributeDefinition(description = "Example")
String x() default "default";
}
@Component(service = MyService.class)
@Designate(ocd = MyComponent.MyConfig.class)
public class MyComponent implements MyService {If you must keep a transition period with Map, use org.osgi.service.component.annotations.Activate with ComponentContext or Map from org.osgi.service.component — not Felix APIs.
@Property / @Properties with metatypeStatic Felix @Property fields become @ObjectClassDefinition + methods with @AttributeDefinition.
// BEFORE (Felix SCR)
@Property(label = "Cron", description = "...")
public static final String CRON = "scheduler.expression";
// AFTER (OSGi DS)
@ObjectClassDefinition(name = "Scheduler Config")
public @interface Config {
@AttributeDefinition(name = "Cron", description = "...")
String scheduler_expression() default "0 0 2 * * ?";
}Bind with @Designate(ocd = MyComponent.Config.class) on the component class.
For rare property = { "key=value" } only (no metatype), you may keep inline property on @Component — prefer OCD for user-facing config.
import org.apache.felix.scr.annotations.* remains@Component uses org.osgi.service.component.annotations@Component(service = ...) (not Felix @Service)@Reference / lifecycle annotations are OSGi DS packages@ObjectClassDefinition / @AttributeDefinition / @Designate where configuration existedmvn clean compile) and components start without SCR descriptor dependency../SKILL.md.tessl-plugin
skills
aem-rde
aem-workflow
code-assessment
content-distribution
create-component
assets
references
dispatcher
incident-response
references
dispatcher-foundation
performance-tuning
references
dispatcher-foundation
security-hardening
references
dispatcher-foundation
technical-advisory
references
dispatcher-foundation
workflow-orchestrator
references
dispatcher-foundation
ensure-agents-md
references
migration
references
dispatcher
legacy-ui
template-modernization
validation
scripts
dispatcher-tool
validate-migration