[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-apache-osgi-scr-migrator":3,"mdc-x5qfg9-key":35,"related-org-apache-osgi-scr-migrator":7027,"related-repo-apache-osgi-scr-migrator":7180},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":22,"repoUrl":23,"updatedAt":24,"license":25,"forks":26,"topics":27,"repo":30,"sourceUrl":33,"mdContent":34},"osgi-scr-migrator","migrate OSGi projects to R6\u002FR7 annotations","Migrate OSGi-based Java projects from deprecated Felix SCR annotations to official OSGi R6\u002FR7 Component annotations. Use when migrating legacy OSGi bundles that use @Component, @Service, @Reference, @Property from org.apache.felix.scr.annotations to org.osgi.service.component.annotations. Handles both Java source code transformation and Maven POM updates (removing maven-scr-plugin, updating dependencies). Also supports Sling-specific annotations like @SlingServlet and @SlingFilter. Features full automation of property migration, metatype configuration generation, constructor injection optimization, validation, and comprehensive reporting. After basic migration, offers optional Step 7 to optimize code with constructor injection for immutable dependencies.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"apache","Apache Software Foundation","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fapache.png",[12,16,19],{"name":13,"slug":14,"type":15},"Java","java","tag",{"name":17,"slug":18,"type":15},"Migration","migration",{"name":20,"slug":21,"type":15},"Engineering","engineering",48,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fsling-whiteboard","2026-07-12T08:32:49.640805",null,32,[28,14,29],"experimental","sling",{"repoUrl":23,"stars":22,"forks":26,"topics":31,"description":32},[28,14,29],"Apache Sling Whiteboard - testing ground for new ideas","https:\u002F\u002Fgithub.com\u002Fapache\u002Fsling-whiteboard\u002Ftree\u002FHEAD\u002Fskills\u002Fosgi-scr-migrator","---\nname: osgi-scr-migrator\ndescription: Migrate OSGi-based Java projects from deprecated Felix SCR annotations to official OSGi R6\u002FR7 Component annotations. Use when migrating legacy OSGi bundles that use @Component, @Service, @Reference, @Property from org.apache.felix.scr.annotations to org.osgi.service.component.annotations. Handles both Java source code transformation and Maven POM updates (removing maven-scr-plugin, updating dependencies). Also supports Sling-specific annotations like @SlingServlet and @SlingFilter. Features full automation of property migration, metatype configuration generation, constructor injection optimization, validation, and comprehensive reporting. After basic migration, offers optional Step 7 to optimize code with constructor injection for immutable dependencies.\n---\n\n# OSGi SCR to R6\u002FR7 Migration (Enhanced)\n\nAutomate complete migration from deprecated Felix SCR annotations to official OSGi R6\u002FR7 Component annotations with full property migration, metatype support, and validation.\n\n## Overview\n\nFelix SCR (Service Component Runtime) annotations (`org.apache.felix.scr.annotations.*`) were deprecated and replaced by official OSGi R6 annotations (`org.osgi.service.component.annotations.*`). This skill provides fully automated tools and guidance for complete migration with minimal manual intervention.\n\n## Key Features\n\n- **Full @Property Migration**: Automatically converts all @Property annotations with proper type specifications (:Integer, :Boolean, etc.)\n- **Service Property Type Annotations**: Automatically uses `@ServiceRanking`, `@ServiceDescription`, and `@ServiceVendor` from `org.osgi.service.component.propertytypes` package (requires `org.osgi:org.osgi.service.component` dependency) for standard service properties (preferred over property strings)\n- **Component Property Types**: Generates type-safe configuration interfaces (OSGi R7 best practice)\n  - Automatically converts `Map\u003CString, Object>` to `Config` annotation interfaces\n  - No more manual type conversion with PropertiesUtil\n  - Type-safe, IDE-friendly configuration access\n- **Metatype Configuration**: Detects and generates complete @Designate and @ObjectClassDefinition interfaces with full metadata preservation\n  - Captures @Component label\u002Fdescription → @ObjectClassDefinition name\u002Fdescription\n  - Captures @Property label\u002Fdescription → @AttributeDefinition name\u002Fdescription\n  - Updates @Activate\u002F@Modified methods to use Config type\n- **Sling Annotations**: Fully automates @SlingServlet and @SlingFilter transformations\n- **Constructor Injection Optimization** (Optional Step 7): Automatically migrates components to use constructor injection for immutable dependencies\n  - Moves `@Activate(Config config)` to constructor injection\n  - Migrates mandatory static unary `@Reference` fields to constructor parameters\n  - Makes fields `final` for immutability and thread safety\n  - Preserves optional\u002Fdynamic\u002Fmultiple references as field injection\n- **Enforced Versions**: Uses latest stable versions (component annotations 1.5.1, metatype 1.4.1)\n- **Validation**: Built-in validation checks for migration completeness\n- **Comprehensive Reporting**: Detailed statistics and warnings for all migrations\n- **Version Control Friendly**: No backup files created - use git or other SCM for change tracking\n\n## When to Use\n\n- Migrating legacy OSGi bundles using Felix SCR annotations\n- Upgrading to OSGi R6\u002FR7 standards\n- Modernizing AEM\u002FSling projects\n- Preparing projects for newer OSGi runtime versions\n- Removing maven-scr-plugin dependency\n\n## Prerequisites\n\nBefore using this migration skill, ensure you have:\n\n- **Python 3.7+** - Required to run the migration scripts\n- **Java 17+** - Required for compiling the migrated code (OSGi R6\u002FR7 annotations require Java 17+)\n- **Maven or Gradle** - For building and testing the project\n- **Version Control** - Git or similar (required for rollback capability)\n\n**Note**: The migrated code will use OSGi R6\u002FR7 Component annotations which require Java 17 or higher. Projects on older Java versions must upgrade to Java 17+ as part of this migration.\n\n## Migration Workflow\n\n### Step 1: Assessment and Preparation\n\n**IMPORTANT**: Before migration, commit all your code to git or another version control system. The migration scripts modify files directly without creating backups.\n\n```bash\n# Ensure code is committed\ngit status\ngit add .\ngit commit -m \"Pre-OSGi migration snapshot\"\n\n# Find files with SCR annotations\ngrep -r \"org.apache.felix.scr.annotations\" --include=\"*.java\" .\n\n# Check POM dependencies\ngrep -r \"felix.scr.annotations\" --include=\"pom.xml\" .\n\n# Count components to migrate\ngrep -r \"@Component\" --include=\"*.java\" . | wc -l\n```\n\nCreate a backup or ensure code is in version control before proceeding.\n\n### Step 2: Run Automated Migration\n\nUse the enhanced migration scripts for fully automated transformation:\n\n#### 2a. Migrate Java Annotations (Enhanced)\n\n```bash\n# Dry run to preview changes\npython3 scripts\u002Fmigrate_annotations.py \u002Fpath\u002Fto\u002Fsrc --dry-run\n\n# Apply changes with validation\npython3 scripts\u002Fmigrate_annotations.py \u002Fpath\u002Fto\u002Fsrc --validate\n\n# Tip: Commit to git before running to easily review\u002Frevert changes\ngit add . && git commit -m \"Pre-migration snapshot\"\n```\n\nThe enhanced script handles:\n- Import statement updates\n- `@Component` attribute transformation with property merging\n- `@Service` merging into `@Component`\n- `@Reference` cardinality updates (OPTIONAL_UNARY → OPTIONAL, etc.)\n- **Full `@Property` migration** with type specifications\n- **Automatic metatype configuration generation** for configurable components\n- **Complete `@SlingServlet` transformation** to @Component with servlet properties\n- **Complete `@SlingFilter` transformation** to @Component with filter properties\n- Lifecycle annotation imports (`@Activate`, `@Deactivate`, `@Modified`)\n- Validation and comprehensive reporting\n\n#### 2b. Migrate POM Files (Enhanced)\n\n```bash\n# Dry run to preview changes\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --dry-run\n\n# Apply changes with automatic metatype detection\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --auto-detect-metatype\n\n# Apply with validation\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --validate\n```\n\nThe enhanced script handles:\n- Removing `maven-scr-plugin` from all locations\n- Removing `org.apache.felix.scr.annotations` dependency\n- Adding `org.osgi.service.component.annotations` dependency (version **1.5.1** enforced) **at the beginning of the dependency list**\n- **Smart version detection** from existing OSGi dependencies\n- **Automatic metatype dependency addition** when detected (version **1.4.1** enforced) **placed after component annotations**\n- Ensuring OSGi bundle plugin (`maven-bundle-plugin` or `bnd-maven-plugin`) uses `extensions=true`\n- Removing obsolete SCR-specific plugin instructions\n- Pretty-printing XML with proper indentation\n- Validation and detailed reporting\n\n### Step 3: Review Migration Results\n\nThe scripts now provide comprehensive statistics:\n\n```\n======================================================================\nMIGRATION SUMMARY\n======================================================================\nFiles processed:              15\nFiles changed:                12\n@Component annotations:       45\n@Service merged:              38\n@Reference updated:           27\n@Property migrated:           156\n@SlingServlet migrated:       8\n@SlingFilter migrated:        3\nMetatype configs generated:   12\nImport statements updated:    180\n\nWarnings: 2\n  ⚠ MyService.java: Consider reviewing generated metatype configuration\n  ⚠ OtherService.java: Manual review recommended for complex property\n\nErrors: 0\n======================================================================\n```\n\n### Step 4: Advanced Features\n\n#### Metatype Configuration with Component Property Types (Fully Automated)\n\nFor components with `metatype = true`, the script automatically generates complete metatype configurations using **Component Property Types** (OSGi R7's preferred approach):\n\n- **@Component label\u002Fdescription** → **@ObjectClassDefinition name\u002Fdescription**\n- **@Property label\u002Fdescription** → **@AttributeDefinition name\u002Fdescription**\n- **@Activate(Map\u003CString, Object>)** → **@Activate(Config)** for type-safe access\n\n```java\n\u002F\u002F Before - Using deprecated Map approach\n@Component(metatype = true, label = \"My Service\", description = \"This is my service\")\n@Property(name = \"timeout\", intValue = 30, label = \"Timeout\", description = \"Request timeout in seconds\")\npublic class MyService {\n    @Activate\n    private void activate(Map\u003CString, Object> props) {\n        int timeout = PropertiesUtil.toInteger(props.get(\"timeout\"), 30);\n    }\n}\n\n\u002F\u002F After - Using Component Property Types (automatically generated)\n@Component\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\", description = \"This is my service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\", description = \"Request timeout in seconds\")\n        int timeout() default 30;\n    }\n\n    @Activate\n    private void activate(Config config) {\n        \u002F\u002F Type-safe, no conversion needed!\n        int timeout = config.timeout();\n    }\n}\n```\n\n**Why Component Property Types?**\n- ✅ **Type-safe**: No runtime type conversion errors\n- ✅ **Cleaner**: No PropertiesUtil or manual conversions\n- ✅ **IDE-friendly**: Auto-completion for configuration properties\n- ✅ **Maintainable**: Changes to config structure caught at compile-time\n- ✅ **OSGi R7 standard**: Modern best practice\n\n**Note:** The migration automatically:\n1. Captures all label\u002Fdescription metadata from @Component and @Property\n2. Generates the Config annotation interface\n3. Updates @Activate\u002F@Modified methods to use the Config type instead of Map\n\nThe POM is automatically updated with the OSGi annotations and metatype dependencies using the latest versions:\n```xml\n\u003Cdependency>\n    \u003CgroupId>org.osgi\u003C\u002FgroupId>\n    \u003CartifactId>org.osgi.service.component.annotations\u003C\u002FartifactId>\n    \u003Cversion>1.5.1\u003C\u002Fversion>\n    \u003Cscope>provided\u003C\u002Fscope>\n\u003C\u002Fdependency>\n\u003Cdependency>\n    \u003CgroupId>org.osgi\u003C\u002FgroupId>\n    \u003CartifactId>org.osgi.service.component\u003C\u002FartifactId>\n    \u003Cversion>1.5.1\u003C\u002Fversion>\n    \u003Cscope>provided\u003C\u002Fscope>\n\u003C\u002Fdependency>\n\u003Cdependency>\n    \u003CgroupId>org.osgi\u003C\u002FgroupId>\n    \u003CartifactId>org.osgi.service.metatype.annotations\u003C\u002FartifactId>\n    \u003Cversion>1.4.1\u003C\u002Fversion>\n    \u003Cscope>provided\u003C\u002Fscope>\n\u003C\u002Fdependency>\n```\n\n**Important**: This migration skill enforces the latest stable versions:\n- **org.osgi.service.component.annotations: 1.5.1** (required - provides @Component, @Reference, etc.)\n- **org.osgi.service.component: 1.5.1** (required - provides property type annotations like @ServiceDescription, @ServiceRanking, @ServiceVendor)\n- **org.osgi.service.metatype.annotations: 1.4.1** (required when metatype is used)\n\n**Automatic for Sling Projects**: When Sling servlets\u002Ffilters are detected:\n- **org.apache.sling.servlets.annotations: 1.2.6** (automatically added, provides type-safe Sling annotations)\n\nThese versions are required for proper OSGi R6\u002FR7 compatibility.\n\n#### Sling Annotations (Fully Automated)\n\nSling servlets and filters are completely automated. The migration uses type-safe Sling Servlets Annotations:\n\n```java\n\u002F\u002F Before\n@SlingServlet(\n    paths = \"\u002Fbin\u002Fmyservlet\",\n    methods = {\"GET\", \"POST\"},\n    extensions = {\"html\", \"json\"}\n)\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n\n\u002F\u002F After (automatically generated)\nimport org.apache.sling.servlets.annotations.SlingServletPaths;\nimport org.osgi.service.component.annotations.Component;\nimport javax.servlet.Servlet;\n\n@Component(service = Servlet.class)\n@SlingServletPaths(value = \"\u002Fbin\u002Fmyservlet\")\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n```\n\n**Path-based servlets** use `@SlingServletPaths`:\n```java\n@Component(service = Servlet.class)\n@SlingServletPaths(value = {\"\u002Fbin\u002Fservlet1\", \"\u002Fbin\u002Fservlet2\"})\n```\n\n**Resource-type-based servlets** use `@SlingServletResourceTypes`:\n```java\n@Component(service = Servlet.class)\n@SlingServletResourceTypes(\n    resourceTypes = \"my\u002Fresource\u002Ftype\",\n    selectors = \"print\",\n    extensions = {\"html\", \"pdf\"},\n    methods = {\"GET\", \"POST\"}\n)\n```\n\n**Filters** use `@SlingServletFilter`:\n```java\n@Component(service = Filter.class)\n@SlingServletFilter(\n    scope = SlingServletFilterScope.REQUEST,\n    order = -700,\n    pattern = \"\u002Fcontent\u002F.*\"\n)\n```\n\nThe migration automatically:\n- Detects Sling servlet\u002Ffilter usage in your Java files\n- Adds the `org.apache.sling.servlets.annotations:1.2.6` dependency to your POM\n- Transforms annotations to use the type-safe Sling Servlets Annotations format\n- Updates all necessary imports\n\nSee [references\u002Fannotation-mappings.md](references\u002Fannotation-mappings.md) for detailed examples of all Sling annotation transformations.\n\n### Step 5: Build and Test\n\n```bash\n# Clean and build\nmvn clean install\n\n# Run tests\nmvn test\n\n# Verify bundle activation\n# The migration scripts include validation to catch common issues\n```\n\n### Step 6: Run Validation\n\n```bash\n# Validate Java migrations\npython3 scripts\u002Fmigrate_annotations.py \u002Fpath\u002Fto\u002Fsrc --validate\n\n# Validate POM migrations\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --validate\n\n# Run comprehensive test suite\nbash scripts\u002Ftests\u002Frun_tests.sh\n```\n\n**✅ Basic migration complete!** If all tests pass, proceed to Step 7 for optional constructor injection optimization.\n\n---\n\n## ✨ Optional Post-Migration Optimization\n\nOnce the basic migration (Steps 1-6) is complete and all tests pass, consider **Step 7** below to further modernize your code with constructor injection.\n\n---\n\n### Step 7: Optimize with Constructor Injection (Automated, Optional)\n\n**⚠️ IMPORTANT**: Run this step AFTER completing Steps 1-6 and ensuring all tests pass.\n\nAutomatically optimize your code with modern OSGi best practices using **constructor injection**. This step is optional but highly recommended for cleaner, more maintainable code.\n\n**NEW**: This step is now fully automated using the `migrate_constructor_injection.py` script!\n\n#### Quick Start - Run the Migration\n\n```bash\n# Preview changes (dry-run) - RECOMMENDED FIRST\npython3 scripts\u002Fmigrate_constructor_injection.py \u002Fpath\u002Fto\u002Fsrc --dry-run\n\n# Apply migration with validation\npython3 scripts\u002Fmigrate_constructor_injection.py \u002Fpath\u002Fto\u002Fsrc --validate\n\n# Single file migration\npython3 scripts\u002Fmigrate_constructor_injection.py \u002Fpath\u002Fto\u002FMyService.java\n\n# Tip: Always commit to git before running\ngit add . && git commit -m \"Pre-constructor-injection snapshot\"\n```\n\n#### Benefits of Constructor Injection\n\n- ✅ **Immutability**: Dependencies declared as `final` fields\n- ✅ **Explicit Dependencies**: All dependencies visible in constructor signature\n- ✅ **Thread Safety**: Immutable references eliminate race conditions\n- ✅ **Testability**: Easier to mock dependencies in unit tests\n- ✅ **Modern Best Practice**: Aligned with OSGi R7\u002FR8 recommendations\n\n#### 7a. Constructor Injection for Configurations\n\nInstead of using `@Activate` methods to receive configuration, inject it directly in the constructor:\n\n```java\n\u002F\u002F After basic migration (Step 2)\n@Component\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\")\n        int timeout() default 30;\n\n        @AttributeDefinition(name = \"Max Retries\")\n        int maxRetries() default 3;\n    }\n\n    private int timeout;\n    private int maxRetries;\n\n    @Activate\n    private void activate(Config config) {\n        this.timeout = config.timeout();\n        this.maxRetries = config.maxRetries();\n    }\n}\n\n\u002F\u002F After optimization (Step 7)\n@Component\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\")\n        int timeout() default 30;\n\n        @AttributeDefinition(name = \"Max Retries\")\n        int maxRetries() default 3;\n    }\n\n    private final int timeout;\n    private final int maxRetries;\n\n    @Activate\n    public MyService(Config config) {\n        this.timeout = config.timeout();\n        this.maxRetries = config.maxRetries();\n    }\n}\n```\n\n**Key changes:**\n- Constructor is now `public` (OSGi requirement for constructor injection)\n- Configuration fields are `final` (immutable)\n- No separate `@Activate` method needed\n- Configuration is available immediately upon construction\n\n#### 7b. Constructor Injection for Unary Static Mandatory References\n\nFor references that are:\n- **Mandatory** (not optional)\n- **Static** (not dynamic)\n- **Unary** (single reference, not multiple)\n\nUse constructor injection to make dependencies explicit and immutable:\n\n```java\n\u002F\u002F After basic migration (Step 2) - Field injection\n@Component(service = MyService.class)\npublic class MyService {\n\n    @Reference\n    private ResourceResolverFactory resolverFactory;\n\n    @Reference\n    private SlingRepository repository;\n\n    @Reference(cardinality = ReferenceCardinality.OPTIONAL)\n    private ConfigurationAdmin configAdmin;  \u002F\u002F Optional - keep as field\n\n    public void doSomething() {\n        \u002F\u002F Use resolverFactory and repository\n    }\n}\n\n\u002F\u002F After optimization (Step 7) - Constructor injection for mandatory references\n@Component(service = MyService.class)\npublic class MyService {\n\n    private final ResourceResolverFactory resolverFactory;\n    private final SlingRepository repository;\n\n    \u002F\u002F Optional reference stays as field injection\n    @Reference(cardinality = ReferenceCardinality.OPTIONAL)\n    private ConfigurationAdmin configAdmin;\n\n    @Activate\n    public MyService(\n        @Reference ResourceResolverFactory resolverFactory,\n        @Reference SlingRepository repository\n    ) {\n        this.resolverFactory = resolverFactory;\n        this.repository = repository;\n    }\n\n    public void doSomething() {\n        \u002F\u002F Use resolverFactory and repository (guaranteed non-null)\n    }\n}\n```\n\n**When to use constructor injection for references:**\n- ✅ Mandatory references (`cardinality = MANDATORY` or no cardinality specified)\n- ✅ Static references (`policy = STATIC` or no policy specified)\n- ✅ Unary references (single service, not collections)\n\n**When to keep field injection:**\n- ❌ Optional references (`cardinality = OPTIONAL`)\n- ❌ Dynamic references (`policy = DYNAMIC`)\n- ❌ Multiple references (`cardinality = MULTIPLE` or `AT_LEAST_ONE`)\n- ❌ References with custom bind\u002Funbind methods\n\n#### 7c. Combined Configuration and References\n\nYou can combine configuration and reference injection in a single constructor:\n\n```java\n\u002F\u002F Optimized: Constructor injection for config + mandatory static references\n@Component(service = MyService.class)\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\")\n        int timeout() default 30;\n    }\n\n    private final int timeout;\n    private final ResourceResolverFactory resolverFactory;\n    private final SlingRepository repository;\n\n    \u002F\u002F Optional\u002Fdynamic references stay as field injection\n    @Reference(cardinality = ReferenceCardinality.OPTIONAL)\n    private ConfigurationAdmin configAdmin;\n\n    @Activate\n    public MyService(\n        Config config,\n        @Reference ResourceResolverFactory resolverFactory,\n        @Reference SlingRepository repository\n    ) {\n        this.timeout = config.timeout();\n        this.resolverFactory = resolverFactory;\n        this.repository = repository;\n    }\n}\n```\n\n**Important notes:**\n- Configuration parameter (if present) must be **first** in constructor\n- Reference parameters follow after configuration\n- Constructor must be `public` for OSGi to inject dependencies\n- Use `@Reference` annotation on each reference parameter\n- Reference attributes (target, cardinality, etc.) can be specified on parameters\n\n#### 7d. What the Script Does Automatically\n\nThe script automatically:\n- ✅ Identifies components with `@Activate(Config config)` methods\n- ✅ Identifies mandatory static unary `@Reference` fields\n- ✅ Creates public constructor with `@Activate` annotation\n- ✅ Moves config parameter to constructor (first parameter)\n- ✅ Moves eligible references to constructor parameters\n- ✅ Makes fields `final` for immutability\n- ✅ Preserves optional\u002Fdynamic\u002Fmultiple references as field injection\n- ✅ Generates comprehensive migration statistics\n\n**What the script does NOT migrate** (kept as field injection):\n- ❌ Optional references (`cardinality = OPTIONAL`)\n- ❌ Dynamic references (`policy = DYNAMIC`)\n- ❌ Multiple references (`cardinality = MULTIPLE` or `AT_LEAST_ONE`)\n- ❌ References with custom bind\u002Funbind methods\n- ❌ Collection references (List, Set, Collection)\n\n#### 7e. Post-Migration Verification\n\nAfter running the automated migration, verify the changes:\n\n1. **Review the migration statistics**:\n   ```\n   ======================================================================\n   CONSTRUCTOR INJECTION MIGRATION SUMMARY\n   ======================================================================\n   Files processed:              15\n   Files changed:                8\n   Components migrated:          8\n   Configs converted:            6\n   References converted:         14\n   Fields made final:            20\n   ======================================================================\n   ```\n\n2. **Test thoroughly**:\n   ```bash\n   mvn clean install\n   mvn test\n   ```\n\n3. **Verify OSGi activation**:\n   - Check OSGi console for component activation\n   - Verify all references are satisfied\n   - Test component functionality\n\n4. **Review generated constructors**:\n   - Constructor is `public` ✓\n   - `@Activate` annotation on constructor ✓\n   - Config parameter is first (if present) ✓\n   - Only mandatory static unary references moved to constructor ✓\n   - Optional\u002Fdynamic references remain as fields ✓\n   - Fields are `final` where appropriate ✓\n\n**If tests fail**: Use `git diff` to review changes and `git checkout .` to revert if needed.\n\n## Advanced Usage\n\n### Command-Line Options\n\n#### Constructor Injection Migration Script (Step 7)\n\n```bash\npython3 scripts\u002Fmigrate_constructor_injection.py [OPTIONS] PATH\n\nOptions:\n  --dry-run          Preview changes without modifying files\n  --validate         Validate migrated code for common issues\n\nExamples:\n  # Preview all changes\n  python3 scripts\u002Fmigrate_constructor_injection.py src\u002F --dry-run\n\n  # Migrate with validation\n  python3 scripts\u002Fmigrate_constructor_injection.py src\u002F --validate\n\n  # Single file migration\n  python3 scripts\u002Fmigrate_constructor_injection.py src\u002Fmain\u002Fjava\u002FMyService.java\n\n  # Use git to review changes\n  git diff src\u002F\n```\n\n#### Java Migration Script (Step 2)\n\n```bash\npython3 scripts\u002Fmigrate_annotations.py [OPTIONS] PATH\n\nOptions:\n  --dry-run          Preview changes without modifying files\n  --validate         Validate migrated code for common issues\n\nExamples:\n  # Preview all changes\n  python3 scripts\u002Fmigrate_annotations.py src\u002F --dry-run\n\n  # Migrate with validation\n  python3 scripts\u002Fmigrate_annotations.py src\u002F --validate\n\n  # Use git to review changes\n  git diff src\u002F\n```\n\n#### POM Migration Script\n\n```bash\npython3 scripts\u002Fmigrate_pom.py [OPTIONS] PATH\n\nOptions:\n  --dry-run              Preview changes without modifying files\n  --validate             Validate migrated POMs\n  --add-metatype         Add metatype dependency\n  --auto-detect-metatype Auto-detect metatype usage from Java files\n  --detect-versions      Detect OSGi versions from existing deps (default: True)\n\nExamples:\n  # Migrate with automatic metatype detection\n  python3 scripts\u002Fmigrate_pom.py . --auto-detect-metatype\n\n  # Dry run with validation\n  python3 scripts\u002Fmigrate_pom.py . --dry-run --validate\n\n  # Use git to review changes\n  git diff pom.xml\n```\n\n### Testing\n\nThe skill includes comprehensive unit tests:\n\n```bash\n# Run all tests\nbash scripts\u002Ftests\u002Frun_tests.sh\n\n# Run Java migration tests\npython3 scripts\u002Ftests\u002Ftest_migrate_annotations.py\n\n# Run POM migration tests\npython3 scripts\u002Ftests\u002Ftest_migrate_pom.py\n\n# Run constructor injection migration tests\npython3 scripts\u002Ftests\u002Ftest_migrate_constructor_injection.py\n```\n\nTest coverage includes:\n- Property parsing and conversion\n- Metatype configuration generation\n- Sling annotation transformation\n- Reference cardinality migration\n- Complete file migration scenarios\n- POM plugin and dependency updates\n- Version detection\n- Statistics tracking\n- **Constructor injection migration** (config and reference conversion)\n- **Reference eligibility detection** (mandatory\u002Foptional, static\u002Fdynamic)\n- **Field final modifier addition**\n\n## Migration Patterns\n\n### Pattern 1: Basic Component with Properties\n\n```java\n\u002F\u002F Before\n@Component(immediate = true)\n@Service\n@Property(name = \"service.vendor\", value = \"Apache Software Foundation\")\n@Property(name = \"service.ranking\", intValue = 100)\npublic class MyService implements SomeInterface {\n}\n\n\u002F\u002F After (fully automated)\n@Component(\n    immediate = true,\n    service = SomeInterface.class,\n    property = {\n        \"service.vendor=Apache Software Foundation\",\n        \"service.ranking:Integer=100\"\n    }\n)\npublic class MyService implements SomeInterface {\n}\n```\n\n### Pattern 2: Configurable Component with Component Property Types\n\n```java\n\u002F\u002F Before - Using deprecated Map approach\n@Component(metatype = true, immediate = true, label = \"My Service\", description = \"Service description\")\n@Property(name = \"timeout\", intValue = 30, label = \"Timeout\", description = \"Request timeout\")\n@Property(name = \"retries\", intValue = 3, label = \"Retries\", description = \"Number of retries\")\npublic class MyService {\n    @Activate\n    private void activate(Map\u003CString, Object> props) {\n        int timeout = PropertiesUtil.toInteger(props.get(\"timeout\"), 30);\n        int retries = PropertiesUtil.toInteger(props.get(\"retries\"), 3);\n    }\n}\n\n\u002F\u002F After - Using Component Property Types (fully automated, type-safe)\n@Component(immediate = true)\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\", description = \"Service description\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\", description = \"Request timeout\")\n        int timeout() default 30;\n\n        @AttributeDefinition(name = \"Retries\", description = \"Number of retries\")\n        int retries() default 3;\n    }\n\n    @Activate\n    private void activate(Config config) {\n        \u002F\u002F Type-safe access - no conversion utilities needed!\n        int timeout = config.timeout();\n        int retries = config.retries();\n    }\n}\n```\n\n**Note**: Component Property Types are the OSGi R7 best practice and are automatically generated by the migration.\n\n### Pattern 3: Sling Servlet\n\n```java\n\u002F\u002F Before\n@SlingServlet(\n    resourceTypes = \"my\u002Fresource\u002Ftype\",\n    selectors = {\"print\", \"pdf\"},\n    extensions = \"html\"\n)\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n\n\u002F\u002F After (fully automated using Sling Servlets Annotations)\nimport org.apache.sling.servlets.annotations.SlingServletResourceTypes;\nimport org.osgi.service.component.annotations.Component;\nimport javax.servlet.Servlet;\n\n@Component(service = Servlet.class)\n@SlingServletResourceTypes(\n    resourceTypes = \"my\u002Fresource\u002Ftype\",\n    selectors = {\"print\", \"pdf\"},\n    extensions = \"html\"\n)\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n```\n\n## Reference Documentation\n\nFor comprehensive annotation mappings and examples:\n\n```bash\n# View complete mapping reference\ncat references\u002Fannotation-mappings.md\n```\n\nThis includes:\n- All annotation transformations with before\u002Fafter examples\n- Cardinality and policy mappings\n- Property type specifications\n- Sling annotation patterns\n- Common migration patterns\n\n## Troubleshooting\n\n### Components Not Activating\n\nCheck:\n- `service` attribute properly set in `@Component`\n- All required dependencies satisfied\n- No compilation errors\n- Run validation: `python3 scripts\u002Fmigrate_annotations.py src\u002F --validate`\n\n### Configuration Not Working\n\n- Verify metatype annotations are present\n- Check `@Designate` links to correct config interface\n- Ensure activate method signature matches config type\n- POM contains metatype dependency (auto-added with `--auto-detect-metatype`)\n\n### Build Failures\n\n- Ensure OSGi bundle plugin (`maven-bundle-plugin` or `bnd-maven-plugin`) has `extensions=true` (auto-fixed)\n- Verify all OSGi annotation dependencies are present (auto-added)\n- Run POM validation: `python3 scripts\u002Fmigrate_pom.py . --validate`\n- Check migration summary for errors and warnings\n\n### Migration Issues\n\nIf you encounter any issues:\n\n1. **Review the statistics**: The summary shows exactly what was changed\n2. **Check warnings**: The script flags items that may need review\n3. **Use dry-run**: Preview changes before applying them\n4. **Run tests**: Use the included test suite to verify migration logic\n5. **Validate**: Use `--validate` flag to check for common issues\n\n## Performance\n\nThe enhanced migration scripts are optimized for large codebases:\n\n- Processes hundreds of files per second\n- Memory-efficient line-by-line processing\n- Parallel processing support (via multiple script invocations)\n- Progress reporting for large projects\n\nExample performance:\n- 500 Java files: ~30 seconds\n- 1000 Java files: ~1 minute\n- 50 POM files: ~5 seconds\n\n## What's New in Enhanced Version\n\n### Version 2.1 Features (Latest)\n\n- ✅ **Constructor Injection Automation**: NEW! Automated Step 7 optimization for modern OSGi best practices\n- ✅ **Immutable Dependencies**: Automatically makes fields `final` when migrated to constructor\n- ✅ **Smart Reference Detection**: Identifies eligible vs ineligible references for constructor injection\n- ✅ **Config Parameter Migration**: Moves `@Activate(Config config)` to constructor injection\n\n### Version 2.0 Features\n\n- ✅ **Full Property Migration**: Complete automation of @Property transformations\n- ✅ **Metatype Generation**: Automatic configuration interface creation\n- ✅ **Sling Automation**: Complete @SlingServlet and @SlingFilter migration\n- ✅ **Smart Version Detection**: Automatic OSGi version inference\n- ✅ **Comprehensive Validation**: Built-in checks for migration quality\n- ✅ **Detailed Reporting**: Statistics and warnings for all operations\n- ✅ **Test Suite**: Comprehensive unit and integration tests\n- ✅ **Error Recovery**: Graceful handling of edge cases\n\n### Improvements Over Original\n\n| Feature | Original | Enhanced | v2.1 |\n|---------|----------|----------|------|\n| @Property Migration | TODO comments | Fully automated | ✓ |\n| Metatype Support | Manual | Auto-generated | ✓ |\n| Sling Annotations | TODO comments | Fully automated | ✓ |\n| Constructor Injection | Not available | Manual guidance | **Fully automated** |\n| Validation | None | Comprehensive | ✓ |\n| Reporting | Basic | Detailed stats | ✓ |\n| Testing | None | Full test suite | Enhanced |\n| Version Detection | Hardcoded | Smart detection | ✓ |\n| Error Handling | Basic | Robust | ✓ |\n\n## Additional Resources\n\n- OSGi Compendium Specification: Component annotations (Chapter 112)\n- Apache Felix SCR documentation\n- Sling development documentation for servlet\u002Ffilter annotations\n- Apache Sling Servlets Annotations: https:\u002F\u002Fgithub.com\u002Fapache\u002Fsling-org-apache-sling-servlets-annotations\n- Test suite: `scripts\u002Ftests\u002F`\n- Example transformations: `references\u002Fannotation-mappings.md`\n\n## Sling-Specific Features\n\nFor **Apache Sling projects**, the migration provides full automation:\n\n1. **Automatic Detection**: The migration automatically detects Sling servlet and filter usage by scanning your Java files for:\n   - `@SlingServlet` annotations\n   - `@SlingFilter` annotations\n   - Existing `@SlingServletPaths`, `@SlingServletResourceTypes`, or `@SlingServletFilter` annotations\n\n2. **Dependency Management**: When Sling usage is detected, the migration automatically:\n   - Adds the `org.apache.sling.servlets.annotations:1.2.6` dependency to your POM\n   - Places it after OSGi component and metatype dependencies\n   - Sets the correct scope (`provided`)\n\n3. **Type-Safe Transformations**: The migration uses type-safe Sling Servlets Annotations:\n   - `@SlingServletPaths` for path-based servlets\n   - `@SlingServletResourceTypes` for resource-type-based servlets with selectors, extensions, and methods\n   - `@SlingServletFilter` for filters with scope, order, and pattern\n\n   This provides better IDE support, compile-time validation, and improved readability compared to property strings.\n\nSee [Sling annotation examples](references\u002Fannotation-mappings.md#sling-annotations) for detailed transformation syntax.\n\n## Notes\n\n- The migration scripts now handle **98%+ of migrations automatically** (including Step 7 constructor injection!)\n- Manual review is only needed for very complex edge cases\n- Always test in a development environment before production deployment\n- **Java 17+ is required** for OSGi R6\u002FR7 Component annotations (this is a prerequisite, not optional)\n- Run the test suite to verify migration logic: `bash scripts\u002Ftests\u002Frun_tests.sh`\n- Some runtime behavior may differ subtly between SCR and R6+ implementations\n- **Step 7 is optional** but recommended - the automated script makes it easy and safe to apply\n",{"data":36,"body":37},{"name":4,"description":6},{"type":38,"children":39},"root",[40,49,55,62,84,90,346,352,380,386,391,434,444,450,457,467,768,773,779,784,791,925,930,1068,1074,1178,1182,1307,1313,1318,1328,1334,1340,1359,1407,1637,1645,1704,1714,1733,1738,1882,1892,1925,1935,1948,1953,1959,1964,2110,2128,2150,2166,2227,2243,2297,2302,2333,2346,2352,2435,2441,2536,2546,2550,2556,2568,2571,2577,2587,2599,2617,2623,2782,2788,2853,2859,2871,3239,3247,3292,3298,3303,3336,3341,3663,3671,3705,3713,3764,3770,3775,3995,4003,4052,4058,4063,4133,4143,4191,4197,4202,4353,4379,4385,4391,4397,4649,4655,4851,4857,5162,5168,5173,5280,5285,5356,5362,5368,5520,5526,5775,5784,5790,5955,5961,5966,5994,5999,6027,6033,6039,6044,6084,6090,6128,6134,6183,6189,6194,6254,6260,6265,6288,6293,6311,6317,6323,6383,6389,6480,6486,6719,6725,6776,6782,6794,6942,6954,6960,7021],{"type":41,"tag":42,"props":43,"children":45},"element","h1",{"id":44},"osgi-scr-to-r6r7-migration-enhanced",[46],{"type":47,"value":48},"text","OSGi SCR to R6\u002FR7 Migration (Enhanced)",{"type":41,"tag":50,"props":51,"children":52},"p",{},[53],{"type":47,"value":54},"Automate complete migration from deprecated Felix SCR annotations to official OSGi R6\u002FR7 Component annotations with full property migration, metatype support, and validation.",{"type":41,"tag":56,"props":57,"children":59},"h2",{"id":58},"overview",[60],{"type":47,"value":61},"Overview",{"type":41,"tag":50,"props":63,"children":64},{},[65,67,74,76,82],{"type":47,"value":66},"Felix SCR (Service Component Runtime) annotations (",{"type":41,"tag":68,"props":69,"children":71},"code",{"className":70},[],[72],{"type":47,"value":73},"org.apache.felix.scr.annotations.*",{"type":47,"value":75},") were deprecated and replaced by official OSGi R6 annotations (",{"type":41,"tag":68,"props":77,"children":79},{"className":78},[],[80],{"type":47,"value":81},"org.osgi.service.component.annotations.*",{"type":47,"value":83},"). This skill provides fully automated tools and guidance for complete migration with minimal manual intervention.",{"type":41,"tag":56,"props":85,"children":87},{"id":86},"key-features",[88],{"type":47,"value":89},"Key Features",{"type":41,"tag":91,"props":92,"children":93},"ul",{},[94,118,167,211,239,249,306,316,326,336],{"type":41,"tag":95,"props":96,"children":97},"li",{},[98,104,106,110,112,116],{"type":41,"tag":99,"props":100,"children":101},"strong",{},[102],{"type":47,"value":103},"Full @Property Migration",{"type":47,"value":105},": Automatically converts all @Property annotations with proper type specifications (",{"type":41,"tag":107,"props":108,"children":109},"integer",{},[],{"type":47,"value":111},", ",{"type":41,"tag":113,"props":114,"children":115},"boolean",{},[],{"type":47,"value":117},", etc.)",{"type":41,"tag":95,"props":119,"children":120},{},[121,126,128,134,135,141,143,149,151,157,159,165],{"type":41,"tag":99,"props":122,"children":123},{},[124],{"type":47,"value":125},"Service Property Type Annotations",{"type":47,"value":127},": Automatically uses ",{"type":41,"tag":68,"props":129,"children":131},{"className":130},[],[132],{"type":47,"value":133},"@ServiceRanking",{"type":47,"value":111},{"type":41,"tag":68,"props":136,"children":138},{"className":137},[],[139],{"type":47,"value":140},"@ServiceDescription",{"type":47,"value":142},", and ",{"type":41,"tag":68,"props":144,"children":146},{"className":145},[],[147],{"type":47,"value":148},"@ServiceVendor",{"type":47,"value":150}," from ",{"type":41,"tag":68,"props":152,"children":154},{"className":153},[],[155],{"type":47,"value":156},"org.osgi.service.component.propertytypes",{"type":47,"value":158}," package (requires ",{"type":41,"tag":68,"props":160,"children":162},{"className":161},[],[163],{"type":47,"value":164},"org.osgi:org.osgi.service.component",{"type":47,"value":166}," dependency) for standard service properties (preferred over property strings)",{"type":41,"tag":95,"props":168,"children":169},{},[170,175,177],{"type":41,"tag":99,"props":171,"children":172},{},[173],{"type":47,"value":174},"Component Property Types",{"type":47,"value":176},": Generates type-safe configuration interfaces (OSGi R7 best practice)\n",{"type":41,"tag":91,"props":178,"children":179},{},[180,201,206],{"type":41,"tag":95,"props":181,"children":182},{},[183,185,191,193,199],{"type":47,"value":184},"Automatically converts ",{"type":41,"tag":68,"props":186,"children":188},{"className":187},[],[189],{"type":47,"value":190},"Map\u003CString, Object>",{"type":47,"value":192}," to ",{"type":41,"tag":68,"props":194,"children":196},{"className":195},[],[197],{"type":47,"value":198},"Config",{"type":47,"value":200}," annotation interfaces",{"type":41,"tag":95,"props":202,"children":203},{},[204],{"type":47,"value":205},"No more manual type conversion with PropertiesUtil",{"type":41,"tag":95,"props":207,"children":208},{},[209],{"type":47,"value":210},"Type-safe, IDE-friendly configuration access",{"type":41,"tag":95,"props":212,"children":213},{},[214,219,221],{"type":41,"tag":99,"props":215,"children":216},{},[217],{"type":47,"value":218},"Metatype Configuration",{"type":47,"value":220},": Detects and generates complete @Designate and @ObjectClassDefinition interfaces with full metadata preservation\n",{"type":41,"tag":91,"props":222,"children":223},{},[224,229,234],{"type":41,"tag":95,"props":225,"children":226},{},[227],{"type":47,"value":228},"Captures @Component label\u002Fdescription → @ObjectClassDefinition name\u002Fdescription",{"type":41,"tag":95,"props":230,"children":231},{},[232],{"type":47,"value":233},"Captures @Property label\u002Fdescription → @AttributeDefinition name\u002Fdescription",{"type":41,"tag":95,"props":235,"children":236},{},[237],{"type":47,"value":238},"Updates @Activate\u002F@Modified methods to use Config type",{"type":41,"tag":95,"props":240,"children":241},{},[242,247],{"type":41,"tag":99,"props":243,"children":244},{},[245],{"type":47,"value":246},"Sling Annotations",{"type":47,"value":248},": Fully automates @SlingServlet and @SlingFilter transformations",{"type":41,"tag":95,"props":250,"children":251},{},[252,257,259],{"type":41,"tag":99,"props":253,"children":254},{},[255],{"type":47,"value":256},"Constructor Injection Optimization",{"type":47,"value":258}," (Optional Step 7): Automatically migrates components to use constructor injection for immutable dependencies\n",{"type":41,"tag":91,"props":260,"children":261},{},[262,275,288,301],{"type":41,"tag":95,"props":263,"children":264},{},[265,267,273],{"type":47,"value":266},"Moves ",{"type":41,"tag":68,"props":268,"children":270},{"className":269},[],[271],{"type":47,"value":272},"@Activate(Config config)",{"type":47,"value":274}," to constructor injection",{"type":41,"tag":95,"props":276,"children":277},{},[278,280,286],{"type":47,"value":279},"Migrates mandatory static unary ",{"type":41,"tag":68,"props":281,"children":283},{"className":282},[],[284],{"type":47,"value":285},"@Reference",{"type":47,"value":287}," fields to constructor parameters",{"type":41,"tag":95,"props":289,"children":290},{},[291,293,299],{"type":47,"value":292},"Makes fields ",{"type":41,"tag":68,"props":294,"children":296},{"className":295},[],[297],{"type":47,"value":298},"final",{"type":47,"value":300}," for immutability and thread safety",{"type":41,"tag":95,"props":302,"children":303},{},[304],{"type":47,"value":305},"Preserves optional\u002Fdynamic\u002Fmultiple references as field injection",{"type":41,"tag":95,"props":307,"children":308},{},[309,314],{"type":41,"tag":99,"props":310,"children":311},{},[312],{"type":47,"value":313},"Enforced Versions",{"type":47,"value":315},": Uses latest stable versions (component annotations 1.5.1, metatype 1.4.1)",{"type":41,"tag":95,"props":317,"children":318},{},[319,324],{"type":41,"tag":99,"props":320,"children":321},{},[322],{"type":47,"value":323},"Validation",{"type":47,"value":325},": Built-in validation checks for migration completeness",{"type":41,"tag":95,"props":327,"children":328},{},[329,334],{"type":41,"tag":99,"props":330,"children":331},{},[332],{"type":47,"value":333},"Comprehensive Reporting",{"type":47,"value":335},": Detailed statistics and warnings for all migrations",{"type":41,"tag":95,"props":337,"children":338},{},[339,344],{"type":41,"tag":99,"props":340,"children":341},{},[342],{"type":47,"value":343},"Version Control Friendly",{"type":47,"value":345},": No backup files created - use git or other SCM for change tracking",{"type":41,"tag":56,"props":347,"children":349},{"id":348},"when-to-use",[350],{"type":47,"value":351},"When to Use",{"type":41,"tag":91,"props":353,"children":354},{},[355,360,365,370,375],{"type":41,"tag":95,"props":356,"children":357},{},[358],{"type":47,"value":359},"Migrating legacy OSGi bundles using Felix SCR annotations",{"type":41,"tag":95,"props":361,"children":362},{},[363],{"type":47,"value":364},"Upgrading to OSGi R6\u002FR7 standards",{"type":41,"tag":95,"props":366,"children":367},{},[368],{"type":47,"value":369},"Modernizing AEM\u002FSling projects",{"type":41,"tag":95,"props":371,"children":372},{},[373],{"type":47,"value":374},"Preparing projects for newer OSGi runtime versions",{"type":41,"tag":95,"props":376,"children":377},{},[378],{"type":47,"value":379},"Removing maven-scr-plugin dependency",{"type":41,"tag":56,"props":381,"children":383},{"id":382},"prerequisites",[384],{"type":47,"value":385},"Prerequisites",{"type":41,"tag":50,"props":387,"children":388},{},[389],{"type":47,"value":390},"Before using this migration skill, ensure you have:",{"type":41,"tag":91,"props":392,"children":393},{},[394,404,414,424],{"type":41,"tag":95,"props":395,"children":396},{},[397,402],{"type":41,"tag":99,"props":398,"children":399},{},[400],{"type":47,"value":401},"Python 3.7+",{"type":47,"value":403}," - Required to run the migration scripts",{"type":41,"tag":95,"props":405,"children":406},{},[407,412],{"type":41,"tag":99,"props":408,"children":409},{},[410],{"type":47,"value":411},"Java 17+",{"type":47,"value":413}," - Required for compiling the migrated code (OSGi R6\u002FR7 annotations require Java 17+)",{"type":41,"tag":95,"props":415,"children":416},{},[417,422],{"type":41,"tag":99,"props":418,"children":419},{},[420],{"type":47,"value":421},"Maven or Gradle",{"type":47,"value":423}," - For building and testing the project",{"type":41,"tag":95,"props":425,"children":426},{},[427,432],{"type":41,"tag":99,"props":428,"children":429},{},[430],{"type":47,"value":431},"Version Control",{"type":47,"value":433}," - Git or similar (required for rollback capability)",{"type":41,"tag":50,"props":435,"children":436},{},[437,442],{"type":41,"tag":99,"props":438,"children":439},{},[440],{"type":47,"value":441},"Note",{"type":47,"value":443},": The migrated code will use OSGi R6\u002FR7 Component annotations which require Java 17 or higher. Projects on older Java versions must upgrade to Java 17+ as part of this migration.",{"type":41,"tag":56,"props":445,"children":447},{"id":446},"migration-workflow",[448],{"type":47,"value":449},"Migration Workflow",{"type":41,"tag":451,"props":452,"children":454},"h3",{"id":453},"step-1-assessment-and-preparation",[455],{"type":47,"value":456},"Step 1: Assessment and Preparation",{"type":41,"tag":50,"props":458,"children":459},{},[460,465],{"type":41,"tag":99,"props":461,"children":462},{},[463],{"type":47,"value":464},"IMPORTANT",{"type":47,"value":466},": Before migration, commit all your code to git or another version control system. The migration scripts modify files directly without creating backups.",{"type":41,"tag":468,"props":469,"children":474},"pre",{"className":470,"code":471,"language":472,"meta":473,"style":473},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Ensure code is committed\ngit status\ngit add .\ngit commit -m \"Pre-OSGi migration snapshot\"\n\n# Find files with SCR annotations\ngrep -r \"org.apache.felix.scr.annotations\" --include=\"*.java\" .\n\n# Check POM dependencies\ngrep -r \"felix.scr.annotations\" --include=\"pom.xml\" .\n\n# Count components to migrate\ngrep -r \"@Component\" --include=\"*.java\" . | wc -l\n","bash","",[475],{"type":41,"tag":68,"props":476,"children":477},{"__ignoreMap":473},[478,490,506,524,558,568,577,627,635,644,690,698,707],{"type":41,"tag":479,"props":480,"children":483},"span",{"class":481,"line":482},"line",1,[484],{"type":41,"tag":479,"props":485,"children":487},{"style":486},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[488],{"type":47,"value":489},"# Ensure code is committed\n",{"type":41,"tag":479,"props":491,"children":493},{"class":481,"line":492},2,[494,500],{"type":41,"tag":479,"props":495,"children":497},{"style":496},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[498],{"type":47,"value":499},"git",{"type":41,"tag":479,"props":501,"children":503},{"style":502},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[504],{"type":47,"value":505}," status\n",{"type":41,"tag":479,"props":507,"children":509},{"class":481,"line":508},3,[510,514,519],{"type":41,"tag":479,"props":511,"children":512},{"style":496},[513],{"type":47,"value":499},{"type":41,"tag":479,"props":515,"children":516},{"style":502},[517],{"type":47,"value":518}," add",{"type":41,"tag":479,"props":520,"children":521},{"style":502},[522],{"type":47,"value":523}," .\n",{"type":41,"tag":479,"props":525,"children":527},{"class":481,"line":526},4,[528,532,537,542,548,553],{"type":41,"tag":479,"props":529,"children":530},{"style":496},[531],{"type":47,"value":499},{"type":41,"tag":479,"props":533,"children":534},{"style":502},[535],{"type":47,"value":536}," commit",{"type":41,"tag":479,"props":538,"children":539},{"style":502},[540],{"type":47,"value":541}," -m",{"type":41,"tag":479,"props":543,"children":545},{"style":544},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[546],{"type":47,"value":547}," \"",{"type":41,"tag":479,"props":549,"children":550},{"style":502},[551],{"type":47,"value":552},"Pre-OSGi migration snapshot",{"type":41,"tag":479,"props":554,"children":555},{"style":544},[556],{"type":47,"value":557},"\"\n",{"type":41,"tag":479,"props":559,"children":561},{"class":481,"line":560},5,[562],{"type":41,"tag":479,"props":563,"children":565},{"emptyLinePlaceholder":564},true,[566],{"type":47,"value":567},"\n",{"type":41,"tag":479,"props":569,"children":571},{"class":481,"line":570},6,[572],{"type":41,"tag":479,"props":573,"children":574},{"style":486},[575],{"type":47,"value":576},"# Find files with SCR annotations\n",{"type":41,"tag":479,"props":578,"children":580},{"class":481,"line":579},7,[581,586,591,595,600,605,610,614,619,623],{"type":41,"tag":479,"props":582,"children":583},{"style":496},[584],{"type":47,"value":585},"grep",{"type":41,"tag":479,"props":587,"children":588},{"style":502},[589],{"type":47,"value":590}," -r",{"type":41,"tag":479,"props":592,"children":593},{"style":544},[594],{"type":47,"value":547},{"type":41,"tag":479,"props":596,"children":597},{"style":502},[598],{"type":47,"value":599},"org.apache.felix.scr.annotations",{"type":41,"tag":479,"props":601,"children":602},{"style":544},[603],{"type":47,"value":604},"\"",{"type":41,"tag":479,"props":606,"children":607},{"style":502},[608],{"type":47,"value":609}," --include=",{"type":41,"tag":479,"props":611,"children":612},{"style":544},[613],{"type":47,"value":604},{"type":41,"tag":479,"props":615,"children":616},{"style":502},[617],{"type":47,"value":618},"*.java",{"type":41,"tag":479,"props":620,"children":621},{"style":544},[622],{"type":47,"value":604},{"type":41,"tag":479,"props":624,"children":625},{"style":502},[626],{"type":47,"value":523},{"type":41,"tag":479,"props":628,"children":630},{"class":481,"line":629},8,[631],{"type":41,"tag":479,"props":632,"children":633},{"emptyLinePlaceholder":564},[634],{"type":47,"value":567},{"type":41,"tag":479,"props":636,"children":638},{"class":481,"line":637},9,[639],{"type":41,"tag":479,"props":640,"children":641},{"style":486},[642],{"type":47,"value":643},"# Check POM dependencies\n",{"type":41,"tag":479,"props":645,"children":647},{"class":481,"line":646},10,[648,652,656,660,665,669,673,677,682,686],{"type":41,"tag":479,"props":649,"children":650},{"style":496},[651],{"type":47,"value":585},{"type":41,"tag":479,"props":653,"children":654},{"style":502},[655],{"type":47,"value":590},{"type":41,"tag":479,"props":657,"children":658},{"style":544},[659],{"type":47,"value":547},{"type":41,"tag":479,"props":661,"children":662},{"style":502},[663],{"type":47,"value":664},"felix.scr.annotations",{"type":41,"tag":479,"props":666,"children":667},{"style":544},[668],{"type":47,"value":604},{"type":41,"tag":479,"props":670,"children":671},{"style":502},[672],{"type":47,"value":609},{"type":41,"tag":479,"props":674,"children":675},{"style":544},[676],{"type":47,"value":604},{"type":41,"tag":479,"props":678,"children":679},{"style":502},[680],{"type":47,"value":681},"pom.xml",{"type":41,"tag":479,"props":683,"children":684},{"style":544},[685],{"type":47,"value":604},{"type":41,"tag":479,"props":687,"children":688},{"style":502},[689],{"type":47,"value":523},{"type":41,"tag":479,"props":691,"children":693},{"class":481,"line":692},11,[694],{"type":41,"tag":479,"props":695,"children":696},{"emptyLinePlaceholder":564},[697],{"type":47,"value":567},{"type":41,"tag":479,"props":699,"children":701},{"class":481,"line":700},12,[702],{"type":41,"tag":479,"props":703,"children":704},{"style":486},[705],{"type":47,"value":706},"# Count components to migrate\n",{"type":41,"tag":479,"props":708,"children":710},{"class":481,"line":709},13,[711,715,719,723,728,732,736,740,744,748,753,758,763],{"type":41,"tag":479,"props":712,"children":713},{"style":496},[714],{"type":47,"value":585},{"type":41,"tag":479,"props":716,"children":717},{"style":502},[718],{"type":47,"value":590},{"type":41,"tag":479,"props":720,"children":721},{"style":544},[722],{"type":47,"value":547},{"type":41,"tag":479,"props":724,"children":725},{"style":502},[726],{"type":47,"value":727},"@Component",{"type":41,"tag":479,"props":729,"children":730},{"style":544},[731],{"type":47,"value":604},{"type":41,"tag":479,"props":733,"children":734},{"style":502},[735],{"type":47,"value":609},{"type":41,"tag":479,"props":737,"children":738},{"style":544},[739],{"type":47,"value":604},{"type":41,"tag":479,"props":741,"children":742},{"style":502},[743],{"type":47,"value":618},{"type":41,"tag":479,"props":745,"children":746},{"style":544},[747],{"type":47,"value":604},{"type":41,"tag":479,"props":749,"children":750},{"style":502},[751],{"type":47,"value":752}," .",{"type":41,"tag":479,"props":754,"children":755},{"style":544},[756],{"type":47,"value":757}," |",{"type":41,"tag":479,"props":759,"children":760},{"style":496},[761],{"type":47,"value":762}," wc",{"type":41,"tag":479,"props":764,"children":765},{"style":502},[766],{"type":47,"value":767}," -l\n",{"type":41,"tag":50,"props":769,"children":770},{},[771],{"type":47,"value":772},"Create a backup or ensure code is in version control before proceeding.",{"type":41,"tag":451,"props":774,"children":776},{"id":775},"step-2-run-automated-migration",[777],{"type":47,"value":778},"Step 2: Run Automated Migration",{"type":41,"tag":50,"props":780,"children":781},{},[782],{"type":47,"value":783},"Use the enhanced migration scripts for fully automated transformation:",{"type":41,"tag":785,"props":786,"children":788},"h4",{"id":787},"_2a-migrate-java-annotations-enhanced",[789],{"type":47,"value":790},"2a. Migrate Java Annotations (Enhanced)",{"type":41,"tag":468,"props":792,"children":794},{"className":470,"code":793,"language":472,"meta":473,"style":473},"# Dry run to preview changes\npython3 scripts\u002Fmigrate_annotations.py \u002Fpath\u002Fto\u002Fsrc --dry-run\n\n# Apply changes with validation\npython3 scripts\u002Fmigrate_annotations.py \u002Fpath\u002Fto\u002Fsrc --validate\n\n# Tip: Commit to git before running to easily review\u002Frevert changes\ngit add . && git commit -m \"Pre-migration snapshot\"\n",[795],{"type":41,"tag":68,"props":796,"children":797},{"__ignoreMap":473},[798,806,829,836,844,864,871,879],{"type":41,"tag":479,"props":799,"children":800},{"class":481,"line":482},[801],{"type":41,"tag":479,"props":802,"children":803},{"style":486},[804],{"type":47,"value":805},"# Dry run to preview changes\n",{"type":41,"tag":479,"props":807,"children":808},{"class":481,"line":492},[809,814,819,824],{"type":41,"tag":479,"props":810,"children":811},{"style":496},[812],{"type":47,"value":813},"python3",{"type":41,"tag":479,"props":815,"children":816},{"style":502},[817],{"type":47,"value":818}," scripts\u002Fmigrate_annotations.py",{"type":41,"tag":479,"props":820,"children":821},{"style":502},[822],{"type":47,"value":823}," \u002Fpath\u002Fto\u002Fsrc",{"type":41,"tag":479,"props":825,"children":826},{"style":502},[827],{"type":47,"value":828}," --dry-run\n",{"type":41,"tag":479,"props":830,"children":831},{"class":481,"line":508},[832],{"type":41,"tag":479,"props":833,"children":834},{"emptyLinePlaceholder":564},[835],{"type":47,"value":567},{"type":41,"tag":479,"props":837,"children":838},{"class":481,"line":526},[839],{"type":41,"tag":479,"props":840,"children":841},{"style":486},[842],{"type":47,"value":843},"# Apply changes with validation\n",{"type":41,"tag":479,"props":845,"children":846},{"class":481,"line":560},[847,851,855,859],{"type":41,"tag":479,"props":848,"children":849},{"style":496},[850],{"type":47,"value":813},{"type":41,"tag":479,"props":852,"children":853},{"style":502},[854],{"type":47,"value":818},{"type":41,"tag":479,"props":856,"children":857},{"style":502},[858],{"type":47,"value":823},{"type":41,"tag":479,"props":860,"children":861},{"style":502},[862],{"type":47,"value":863}," --validate\n",{"type":41,"tag":479,"props":865,"children":866},{"class":481,"line":570},[867],{"type":41,"tag":479,"props":868,"children":869},{"emptyLinePlaceholder":564},[870],{"type":47,"value":567},{"type":41,"tag":479,"props":872,"children":873},{"class":481,"line":579},[874],{"type":41,"tag":479,"props":875,"children":876},{"style":486},[877],{"type":47,"value":878},"# Tip: Commit to git before running to easily review\u002Frevert changes\n",{"type":41,"tag":479,"props":880,"children":881},{"class":481,"line":629},[882,886,890,894,899,904,908,912,916,921],{"type":41,"tag":479,"props":883,"children":884},{"style":496},[885],{"type":47,"value":499},{"type":41,"tag":479,"props":887,"children":888},{"style":502},[889],{"type":47,"value":518},{"type":41,"tag":479,"props":891,"children":892},{"style":502},[893],{"type":47,"value":752},{"type":41,"tag":479,"props":895,"children":896},{"style":544},[897],{"type":47,"value":898}," &&",{"type":41,"tag":479,"props":900,"children":901},{"style":496},[902],{"type":47,"value":903}," git",{"type":41,"tag":479,"props":905,"children":906},{"style":502},[907],{"type":47,"value":536},{"type":41,"tag":479,"props":909,"children":910},{"style":502},[911],{"type":47,"value":541},{"type":41,"tag":479,"props":913,"children":914},{"style":544},[915],{"type":47,"value":547},{"type":41,"tag":479,"props":917,"children":918},{"style":502},[919],{"type":47,"value":920},"Pre-migration snapshot",{"type":41,"tag":479,"props":922,"children":923},{"style":544},[924],{"type":47,"value":557},{"type":41,"tag":50,"props":926,"children":927},{},[928],{"type":47,"value":929},"The enhanced script handles:",{"type":41,"tag":91,"props":931,"children":932},{},[933,938,948,964,974,992,1002,1020,1036,1063],{"type":41,"tag":95,"props":934,"children":935},{},[936],{"type":47,"value":937},"Import statement updates",{"type":41,"tag":95,"props":939,"children":940},{},[941,946],{"type":41,"tag":68,"props":942,"children":944},{"className":943},[],[945],{"type":47,"value":727},{"type":47,"value":947}," attribute transformation with property merging",{"type":41,"tag":95,"props":949,"children":950},{},[951,957,959],{"type":41,"tag":68,"props":952,"children":954},{"className":953},[],[955],{"type":47,"value":956},"@Service",{"type":47,"value":958}," merging into ",{"type":41,"tag":68,"props":960,"children":962},{"className":961},[],[963],{"type":47,"value":727},{"type":41,"tag":95,"props":965,"children":966},{},[967,972],{"type":41,"tag":68,"props":968,"children":970},{"className":969},[],[971],{"type":47,"value":285},{"type":47,"value":973}," cardinality updates (OPTIONAL_UNARY → OPTIONAL, etc.)",{"type":41,"tag":95,"props":975,"children":976},{},[977,990],{"type":41,"tag":99,"props":978,"children":979},{},[980,982,988],{"type":47,"value":981},"Full ",{"type":41,"tag":68,"props":983,"children":985},{"className":984},[],[986],{"type":47,"value":987},"@Property",{"type":47,"value":989}," migration",{"type":47,"value":991}," with type specifications",{"type":41,"tag":95,"props":993,"children":994},{},[995,1000],{"type":41,"tag":99,"props":996,"children":997},{},[998],{"type":47,"value":999},"Automatic metatype configuration generation",{"type":47,"value":1001}," for configurable components",{"type":41,"tag":95,"props":1003,"children":1004},{},[1005,1018],{"type":41,"tag":99,"props":1006,"children":1007},{},[1008,1010,1016],{"type":47,"value":1009},"Complete ",{"type":41,"tag":68,"props":1011,"children":1013},{"className":1012},[],[1014],{"type":47,"value":1015},"@SlingServlet",{"type":47,"value":1017}," transformation",{"type":47,"value":1019}," to @Component with servlet properties",{"type":41,"tag":95,"props":1021,"children":1022},{},[1023,1034],{"type":41,"tag":99,"props":1024,"children":1025},{},[1026,1027,1033],{"type":47,"value":1009},{"type":41,"tag":68,"props":1028,"children":1030},{"className":1029},[],[1031],{"type":47,"value":1032},"@SlingFilter",{"type":47,"value":1017},{"type":47,"value":1035}," to @Component with filter properties",{"type":41,"tag":95,"props":1037,"children":1038},{},[1039,1041,1047,1048,1054,1055,1061],{"type":47,"value":1040},"Lifecycle annotation imports (",{"type":41,"tag":68,"props":1042,"children":1044},{"className":1043},[],[1045],{"type":47,"value":1046},"@Activate",{"type":47,"value":111},{"type":41,"tag":68,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":47,"value":1053},"@Deactivate",{"type":47,"value":111},{"type":41,"tag":68,"props":1056,"children":1058},{"className":1057},[],[1059],{"type":47,"value":1060},"@Modified",{"type":47,"value":1062},")",{"type":41,"tag":95,"props":1064,"children":1065},{},[1066],{"type":47,"value":1067},"Validation and comprehensive reporting",{"type":41,"tag":785,"props":1069,"children":1071},{"id":1070},"_2b-migrate-pom-files-enhanced",[1072],{"type":47,"value":1073},"2b. Migrate POM Files (Enhanced)",{"type":41,"tag":468,"props":1075,"children":1077},{"className":470,"code":1076,"language":472,"meta":473,"style":473},"# Dry run to preview changes\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --dry-run\n\n# Apply changes with automatic metatype detection\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --auto-detect-metatype\n\n# Apply with validation\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --validate\n",[1078],{"type":41,"tag":68,"props":1079,"children":1080},{"__ignoreMap":473},[1081,1088,1109,1116,1124,1144,1151,1159],{"type":41,"tag":479,"props":1082,"children":1083},{"class":481,"line":482},[1084],{"type":41,"tag":479,"props":1085,"children":1086},{"style":486},[1087],{"type":47,"value":805},{"type":41,"tag":479,"props":1089,"children":1090},{"class":481,"line":492},[1091,1095,1100,1105],{"type":41,"tag":479,"props":1092,"children":1093},{"style":496},[1094],{"type":47,"value":813},{"type":41,"tag":479,"props":1096,"children":1097},{"style":502},[1098],{"type":47,"value":1099}," scripts\u002Fmigrate_pom.py",{"type":41,"tag":479,"props":1101,"children":1102},{"style":502},[1103],{"type":47,"value":1104}," \u002Fpath\u002Fto\u002Fproject",{"type":41,"tag":479,"props":1106,"children":1107},{"style":502},[1108],{"type":47,"value":828},{"type":41,"tag":479,"props":1110,"children":1111},{"class":481,"line":508},[1112],{"type":41,"tag":479,"props":1113,"children":1114},{"emptyLinePlaceholder":564},[1115],{"type":47,"value":567},{"type":41,"tag":479,"props":1117,"children":1118},{"class":481,"line":526},[1119],{"type":41,"tag":479,"props":1120,"children":1121},{"style":486},[1122],{"type":47,"value":1123},"# Apply changes with automatic metatype detection\n",{"type":41,"tag":479,"props":1125,"children":1126},{"class":481,"line":560},[1127,1131,1135,1139],{"type":41,"tag":479,"props":1128,"children":1129},{"style":496},[1130],{"type":47,"value":813},{"type":41,"tag":479,"props":1132,"children":1133},{"style":502},[1134],{"type":47,"value":1099},{"type":41,"tag":479,"props":1136,"children":1137},{"style":502},[1138],{"type":47,"value":1104},{"type":41,"tag":479,"props":1140,"children":1141},{"style":502},[1142],{"type":47,"value":1143}," --auto-detect-metatype\n",{"type":41,"tag":479,"props":1145,"children":1146},{"class":481,"line":570},[1147],{"type":41,"tag":479,"props":1148,"children":1149},{"emptyLinePlaceholder":564},[1150],{"type":47,"value":567},{"type":41,"tag":479,"props":1152,"children":1153},{"class":481,"line":579},[1154],{"type":41,"tag":479,"props":1155,"children":1156},{"style":486},[1157],{"type":47,"value":1158},"# Apply with validation\n",{"type":41,"tag":479,"props":1160,"children":1161},{"class":481,"line":629},[1162,1166,1170,1174],{"type":41,"tag":479,"props":1163,"children":1164},{"style":496},[1165],{"type":47,"value":813},{"type":41,"tag":479,"props":1167,"children":1168},{"style":502},[1169],{"type":47,"value":1099},{"type":41,"tag":479,"props":1171,"children":1172},{"style":502},[1173],{"type":47,"value":1104},{"type":41,"tag":479,"props":1175,"children":1176},{"style":502},[1177],{"type":47,"value":863},{"type":41,"tag":50,"props":1179,"children":1180},{},[1181],{"type":47,"value":929},{"type":41,"tag":91,"props":1183,"children":1184},{},[1185,1198,1209,1234,1244,1265,1292,1297,1302],{"type":41,"tag":95,"props":1186,"children":1187},{},[1188,1190,1196],{"type":47,"value":1189},"Removing ",{"type":41,"tag":68,"props":1191,"children":1193},{"className":1192},[],[1194],{"type":47,"value":1195},"maven-scr-plugin",{"type":47,"value":1197}," from all locations",{"type":41,"tag":95,"props":1199,"children":1200},{},[1201,1202,1207],{"type":47,"value":1189},{"type":41,"tag":68,"props":1203,"children":1205},{"className":1204},[],[1206],{"type":47,"value":599},{"type":47,"value":1208}," dependency",{"type":41,"tag":95,"props":1210,"children":1211},{},[1212,1214,1220,1222,1227,1229],{"type":47,"value":1213},"Adding ",{"type":41,"tag":68,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":47,"value":1219},"org.osgi.service.component.annotations",{"type":47,"value":1221}," dependency (version ",{"type":41,"tag":99,"props":1223,"children":1224},{},[1225],{"type":47,"value":1226},"1.5.1",{"type":47,"value":1228}," enforced) ",{"type":41,"tag":99,"props":1230,"children":1231},{},[1232],{"type":47,"value":1233},"at the beginning of the dependency list",{"type":41,"tag":95,"props":1235,"children":1236},{},[1237,1242],{"type":41,"tag":99,"props":1238,"children":1239},{},[1240],{"type":47,"value":1241},"Smart version detection",{"type":47,"value":1243}," from existing OSGi dependencies",{"type":41,"tag":95,"props":1245,"children":1246},{},[1247,1252,1254,1259,1260],{"type":41,"tag":99,"props":1248,"children":1249},{},[1250],{"type":47,"value":1251},"Automatic metatype dependency addition",{"type":47,"value":1253}," when detected (version ",{"type":41,"tag":99,"props":1255,"children":1256},{},[1257],{"type":47,"value":1258},"1.4.1",{"type":47,"value":1228},{"type":41,"tag":99,"props":1261,"children":1262},{},[1263],{"type":47,"value":1264},"placed after component annotations",{"type":41,"tag":95,"props":1266,"children":1267},{},[1268,1270,1276,1278,1284,1286],{"type":47,"value":1269},"Ensuring OSGi bundle plugin (",{"type":41,"tag":68,"props":1271,"children":1273},{"className":1272},[],[1274],{"type":47,"value":1275},"maven-bundle-plugin",{"type":47,"value":1277}," or ",{"type":41,"tag":68,"props":1279,"children":1281},{"className":1280},[],[1282],{"type":47,"value":1283},"bnd-maven-plugin",{"type":47,"value":1285},") uses ",{"type":41,"tag":68,"props":1287,"children":1289},{"className":1288},[],[1290],{"type":47,"value":1291},"extensions=true",{"type":41,"tag":95,"props":1293,"children":1294},{},[1295],{"type":47,"value":1296},"Removing obsolete SCR-specific plugin instructions",{"type":41,"tag":95,"props":1298,"children":1299},{},[1300],{"type":47,"value":1301},"Pretty-printing XML with proper indentation",{"type":41,"tag":95,"props":1303,"children":1304},{},[1305],{"type":47,"value":1306},"Validation and detailed reporting",{"type":41,"tag":451,"props":1308,"children":1310},{"id":1309},"step-3-review-migration-results",[1311],{"type":47,"value":1312},"Step 3: Review Migration Results",{"type":41,"tag":50,"props":1314,"children":1315},{},[1316],{"type":47,"value":1317},"The scripts now provide comprehensive statistics:",{"type":41,"tag":468,"props":1319,"children":1323},{"className":1320,"code":1322,"language":47},[1321],"language-text","======================================================================\nMIGRATION SUMMARY\n======================================================================\nFiles processed:              15\nFiles changed:                12\n@Component annotations:       45\n@Service merged:              38\n@Reference updated:           27\n@Property migrated:           156\n@SlingServlet migrated:       8\n@SlingFilter migrated:        3\nMetatype configs generated:   12\nImport statements updated:    180\n\nWarnings: 2\n  ⚠ MyService.java: Consider reviewing generated metatype configuration\n  ⚠ OtherService.java: Manual review recommended for complex property\n\nErrors: 0\n======================================================================\n",[1324],{"type":41,"tag":68,"props":1325,"children":1326},{"__ignoreMap":473},[1327],{"type":47,"value":1322},{"type":41,"tag":451,"props":1329,"children":1331},{"id":1330},"step-4-advanced-features",[1332],{"type":47,"value":1333},"Step 4: Advanced Features",{"type":41,"tag":785,"props":1335,"children":1337},{"id":1336},"metatype-configuration-with-component-property-types-fully-automated",[1338],{"type":47,"value":1339},"Metatype Configuration with Component Property Types (Fully Automated)",{"type":41,"tag":50,"props":1341,"children":1342},{},[1343,1345,1351,1353,1357],{"type":47,"value":1344},"For components with ",{"type":41,"tag":68,"props":1346,"children":1348},{"className":1347},[],[1349],{"type":47,"value":1350},"metatype = true",{"type":47,"value":1352},", the script automatically generates complete metatype configurations using ",{"type":41,"tag":99,"props":1354,"children":1355},{},[1356],{"type":47,"value":174},{"type":47,"value":1358}," (OSGi R7's preferred approach):",{"type":41,"tag":91,"props":1360,"children":1361},{},[1362,1377,1391],{"type":41,"tag":95,"props":1363,"children":1364},{},[1365,1370,1372],{"type":41,"tag":99,"props":1366,"children":1367},{},[1368],{"type":47,"value":1369},"@Component label\u002Fdescription",{"type":47,"value":1371}," → ",{"type":41,"tag":99,"props":1373,"children":1374},{},[1375],{"type":47,"value":1376},"@ObjectClassDefinition name\u002Fdescription",{"type":41,"tag":95,"props":1378,"children":1379},{},[1380,1385,1386],{"type":41,"tag":99,"props":1381,"children":1382},{},[1383],{"type":47,"value":1384},"@Property label\u002Fdescription",{"type":47,"value":1371},{"type":41,"tag":99,"props":1387,"children":1388},{},[1389],{"type":47,"value":1390},"@AttributeDefinition name\u002Fdescription",{"type":41,"tag":95,"props":1392,"children":1393},{},[1394,1399,1400,1405],{"type":41,"tag":99,"props":1395,"children":1396},{},[1397],{"type":47,"value":1398},"@Activate(Map\u003CString, Object>)",{"type":47,"value":1371},{"type":41,"tag":99,"props":1401,"children":1402},{},[1403],{"type":47,"value":1404},"@Activate(Config)",{"type":47,"value":1406}," for type-safe access",{"type":41,"tag":468,"props":1408,"children":1411},{"className":1409,"code":1410,"language":14,"meta":473,"style":473},"language-java shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Before - Using deprecated Map approach\n@Component(metatype = true, label = \"My Service\", description = \"This is my service\")\n@Property(name = \"timeout\", intValue = 30, label = \"Timeout\", description = \"Request timeout in seconds\")\npublic class MyService {\n    @Activate\n    private void activate(Map\u003CString, Object> props) {\n        int timeout = PropertiesUtil.toInteger(props.get(\"timeout\"), 30);\n    }\n}\n\n\u002F\u002F After - Using Component Property Types (automatically generated)\n@Component\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\", description = \"This is my service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\", description = \"Request timeout in seconds\")\n        int timeout() default 30;\n    }\n\n    @Activate\n    private void activate(Config config) {\n        \u002F\u002F Type-safe, no conversion needed!\n        int timeout = config.timeout();\n    }\n}\n",[1412],{"type":41,"tag":68,"props":1413,"children":1414},{"__ignoreMap":473},[1415,1423,1431,1439,1447,1455,1463,1471,1479,1487,1494,1502,1510,1518,1526,1534,1543,1552,1561,1570,1578,1586,1594,1603,1612,1621,1629],{"type":41,"tag":479,"props":1416,"children":1417},{"class":481,"line":482},[1418],{"type":41,"tag":479,"props":1419,"children":1420},{},[1421],{"type":47,"value":1422},"\u002F\u002F Before - Using deprecated Map approach\n",{"type":41,"tag":479,"props":1424,"children":1425},{"class":481,"line":492},[1426],{"type":41,"tag":479,"props":1427,"children":1428},{},[1429],{"type":47,"value":1430},"@Component(metatype = true, label = \"My Service\", description = \"This is my service\")\n",{"type":41,"tag":479,"props":1432,"children":1433},{"class":481,"line":508},[1434],{"type":41,"tag":479,"props":1435,"children":1436},{},[1437],{"type":47,"value":1438},"@Property(name = \"timeout\", intValue = 30, label = \"Timeout\", description = \"Request timeout in seconds\")\n",{"type":41,"tag":479,"props":1440,"children":1441},{"class":481,"line":526},[1442],{"type":41,"tag":479,"props":1443,"children":1444},{},[1445],{"type":47,"value":1446},"public class MyService {\n",{"type":41,"tag":479,"props":1448,"children":1449},{"class":481,"line":560},[1450],{"type":41,"tag":479,"props":1451,"children":1452},{},[1453],{"type":47,"value":1454},"    @Activate\n",{"type":41,"tag":479,"props":1456,"children":1457},{"class":481,"line":570},[1458],{"type":41,"tag":479,"props":1459,"children":1460},{},[1461],{"type":47,"value":1462},"    private void activate(Map\u003CString, Object> props) {\n",{"type":41,"tag":479,"props":1464,"children":1465},{"class":481,"line":579},[1466],{"type":41,"tag":479,"props":1467,"children":1468},{},[1469],{"type":47,"value":1470},"        int timeout = PropertiesUtil.toInteger(props.get(\"timeout\"), 30);\n",{"type":41,"tag":479,"props":1472,"children":1473},{"class":481,"line":629},[1474],{"type":41,"tag":479,"props":1475,"children":1476},{},[1477],{"type":47,"value":1478},"    }\n",{"type":41,"tag":479,"props":1480,"children":1481},{"class":481,"line":637},[1482],{"type":41,"tag":479,"props":1483,"children":1484},{},[1485],{"type":47,"value":1486},"}\n",{"type":41,"tag":479,"props":1488,"children":1489},{"class":481,"line":646},[1490],{"type":41,"tag":479,"props":1491,"children":1492},{"emptyLinePlaceholder":564},[1493],{"type":47,"value":567},{"type":41,"tag":479,"props":1495,"children":1496},{"class":481,"line":692},[1497],{"type":41,"tag":479,"props":1498,"children":1499},{},[1500],{"type":47,"value":1501},"\u002F\u002F After - Using Component Property Types (automatically generated)\n",{"type":41,"tag":479,"props":1503,"children":1504},{"class":481,"line":700},[1505],{"type":41,"tag":479,"props":1506,"children":1507},{},[1508],{"type":47,"value":1509},"@Component\n",{"type":41,"tag":479,"props":1511,"children":1512},{"class":481,"line":709},[1513],{"type":41,"tag":479,"props":1514,"children":1515},{},[1516],{"type":47,"value":1517},"@Designate(ocd = MyService.Config.class)\n",{"type":41,"tag":479,"props":1519,"children":1521},{"class":481,"line":1520},14,[1522],{"type":41,"tag":479,"props":1523,"children":1524},{},[1525],{"type":47,"value":1446},{"type":41,"tag":479,"props":1527,"children":1529},{"class":481,"line":1528},15,[1530],{"type":41,"tag":479,"props":1531,"children":1532},{"emptyLinePlaceholder":564},[1533],{"type":47,"value":567},{"type":41,"tag":479,"props":1535,"children":1537},{"class":481,"line":1536},16,[1538],{"type":41,"tag":479,"props":1539,"children":1540},{},[1541],{"type":47,"value":1542},"    @ObjectClassDefinition(name = \"My Service\", description = \"This is my service\")\n",{"type":41,"tag":479,"props":1544,"children":1546},{"class":481,"line":1545},17,[1547],{"type":41,"tag":479,"props":1548,"children":1549},{},[1550],{"type":47,"value":1551},"    public @interface Config {\n",{"type":41,"tag":479,"props":1553,"children":1555},{"class":481,"line":1554},18,[1556],{"type":41,"tag":479,"props":1557,"children":1558},{},[1559],{"type":47,"value":1560},"        @AttributeDefinition(name = \"Timeout\", description = \"Request timeout in seconds\")\n",{"type":41,"tag":479,"props":1562,"children":1564},{"class":481,"line":1563},19,[1565],{"type":41,"tag":479,"props":1566,"children":1567},{},[1568],{"type":47,"value":1569},"        int timeout() default 30;\n",{"type":41,"tag":479,"props":1571,"children":1573},{"class":481,"line":1572},20,[1574],{"type":41,"tag":479,"props":1575,"children":1576},{},[1577],{"type":47,"value":1478},{"type":41,"tag":479,"props":1579,"children":1581},{"class":481,"line":1580},21,[1582],{"type":41,"tag":479,"props":1583,"children":1584},{"emptyLinePlaceholder":564},[1585],{"type":47,"value":567},{"type":41,"tag":479,"props":1587,"children":1589},{"class":481,"line":1588},22,[1590],{"type":41,"tag":479,"props":1591,"children":1592},{},[1593],{"type":47,"value":1454},{"type":41,"tag":479,"props":1595,"children":1597},{"class":481,"line":1596},23,[1598],{"type":41,"tag":479,"props":1599,"children":1600},{},[1601],{"type":47,"value":1602},"    private void activate(Config config) {\n",{"type":41,"tag":479,"props":1604,"children":1606},{"class":481,"line":1605},24,[1607],{"type":41,"tag":479,"props":1608,"children":1609},{},[1610],{"type":47,"value":1611},"        \u002F\u002F Type-safe, no conversion needed!\n",{"type":41,"tag":479,"props":1613,"children":1615},{"class":481,"line":1614},25,[1616],{"type":41,"tag":479,"props":1617,"children":1618},{},[1619],{"type":47,"value":1620},"        int timeout = config.timeout();\n",{"type":41,"tag":479,"props":1622,"children":1624},{"class":481,"line":1623},26,[1625],{"type":41,"tag":479,"props":1626,"children":1627},{},[1628],{"type":47,"value":1478},{"type":41,"tag":479,"props":1630,"children":1632},{"class":481,"line":1631},27,[1633],{"type":41,"tag":479,"props":1634,"children":1635},{},[1636],{"type":47,"value":1486},{"type":41,"tag":50,"props":1638,"children":1639},{},[1640],{"type":41,"tag":99,"props":1641,"children":1642},{},[1643],{"type":47,"value":1644},"Why Component Property Types?",{"type":41,"tag":91,"props":1646,"children":1647},{},[1648,1660,1671,1682,1693],{"type":41,"tag":95,"props":1649,"children":1650},{},[1651,1653,1658],{"type":47,"value":1652},"✅ ",{"type":41,"tag":99,"props":1654,"children":1655},{},[1656],{"type":47,"value":1657},"Type-safe",{"type":47,"value":1659},": No runtime type conversion errors",{"type":41,"tag":95,"props":1661,"children":1662},{},[1663,1664,1669],{"type":47,"value":1652},{"type":41,"tag":99,"props":1665,"children":1666},{},[1667],{"type":47,"value":1668},"Cleaner",{"type":47,"value":1670},": No PropertiesUtil or manual conversions",{"type":41,"tag":95,"props":1672,"children":1673},{},[1674,1675,1680],{"type":47,"value":1652},{"type":41,"tag":99,"props":1676,"children":1677},{},[1678],{"type":47,"value":1679},"IDE-friendly",{"type":47,"value":1681},": Auto-completion for configuration properties",{"type":41,"tag":95,"props":1683,"children":1684},{},[1685,1686,1691],{"type":47,"value":1652},{"type":41,"tag":99,"props":1687,"children":1688},{},[1689],{"type":47,"value":1690},"Maintainable",{"type":47,"value":1692},": Changes to config structure caught at compile-time",{"type":41,"tag":95,"props":1694,"children":1695},{},[1696,1697,1702],{"type":47,"value":1652},{"type":41,"tag":99,"props":1698,"children":1699},{},[1700],{"type":47,"value":1701},"OSGi R7 standard",{"type":47,"value":1703},": Modern best practice",{"type":41,"tag":50,"props":1705,"children":1706},{},[1707,1712],{"type":41,"tag":99,"props":1708,"children":1709},{},[1710],{"type":47,"value":1711},"Note:",{"type":47,"value":1713}," The migration automatically:",{"type":41,"tag":1715,"props":1716,"children":1717},"ol",{},[1718,1723,1728],{"type":41,"tag":95,"props":1719,"children":1720},{},[1721],{"type":47,"value":1722},"Captures all label\u002Fdescription metadata from @Component and @Property",{"type":41,"tag":95,"props":1724,"children":1725},{},[1726],{"type":47,"value":1727},"Generates the Config annotation interface",{"type":41,"tag":95,"props":1729,"children":1730},{},[1731],{"type":47,"value":1732},"Updates @Activate\u002F@Modified methods to use the Config type instead of Map",{"type":41,"tag":50,"props":1734,"children":1735},{},[1736],{"type":47,"value":1737},"The POM is automatically updated with the OSGi annotations and metatype dependencies using the latest versions:",{"type":41,"tag":468,"props":1739,"children":1743},{"className":1740,"code":1741,"language":1742,"meta":473,"style":473},"language-xml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cdependency>\n    \u003CgroupId>org.osgi\u003C\u002FgroupId>\n    \u003CartifactId>org.osgi.service.component.annotations\u003C\u002FartifactId>\n    \u003Cversion>1.5.1\u003C\u002Fversion>\n    \u003Cscope>provided\u003C\u002Fscope>\n\u003C\u002Fdependency>\n\u003Cdependency>\n    \u003CgroupId>org.osgi\u003C\u002FgroupId>\n    \u003CartifactId>org.osgi.service.component\u003C\u002FartifactId>\n    \u003Cversion>1.5.1\u003C\u002Fversion>\n    \u003Cscope>provided\u003C\u002Fscope>\n\u003C\u002Fdependency>\n\u003Cdependency>\n    \u003CgroupId>org.osgi\u003C\u002FgroupId>\n    \u003CartifactId>org.osgi.service.metatype.annotations\u003C\u002FartifactId>\n    \u003Cversion>1.4.1\u003C\u002Fversion>\n    \u003Cscope>provided\u003C\u002Fscope>\n\u003C\u002Fdependency>\n","xml",[1744],{"type":41,"tag":68,"props":1745,"children":1746},{"__ignoreMap":473},[1747,1755,1763,1771,1779,1787,1795,1802,1809,1817,1824,1831,1838,1845,1852,1860,1868,1875],{"type":41,"tag":479,"props":1748,"children":1749},{"class":481,"line":482},[1750],{"type":41,"tag":479,"props":1751,"children":1752},{},[1753],{"type":47,"value":1754},"\u003Cdependency>\n",{"type":41,"tag":479,"props":1756,"children":1757},{"class":481,"line":492},[1758],{"type":41,"tag":479,"props":1759,"children":1760},{},[1761],{"type":47,"value":1762},"    \u003CgroupId>org.osgi\u003C\u002FgroupId>\n",{"type":41,"tag":479,"props":1764,"children":1765},{"class":481,"line":508},[1766],{"type":41,"tag":479,"props":1767,"children":1768},{},[1769],{"type":47,"value":1770},"    \u003CartifactId>org.osgi.service.component.annotations\u003C\u002FartifactId>\n",{"type":41,"tag":479,"props":1772,"children":1773},{"class":481,"line":526},[1774],{"type":41,"tag":479,"props":1775,"children":1776},{},[1777],{"type":47,"value":1778},"    \u003Cversion>1.5.1\u003C\u002Fversion>\n",{"type":41,"tag":479,"props":1780,"children":1781},{"class":481,"line":560},[1782],{"type":41,"tag":479,"props":1783,"children":1784},{},[1785],{"type":47,"value":1786},"    \u003Cscope>provided\u003C\u002Fscope>\n",{"type":41,"tag":479,"props":1788,"children":1789},{"class":481,"line":570},[1790],{"type":41,"tag":479,"props":1791,"children":1792},{},[1793],{"type":47,"value":1794},"\u003C\u002Fdependency>\n",{"type":41,"tag":479,"props":1796,"children":1797},{"class":481,"line":579},[1798],{"type":41,"tag":479,"props":1799,"children":1800},{},[1801],{"type":47,"value":1754},{"type":41,"tag":479,"props":1803,"children":1804},{"class":481,"line":629},[1805],{"type":41,"tag":479,"props":1806,"children":1807},{},[1808],{"type":47,"value":1762},{"type":41,"tag":479,"props":1810,"children":1811},{"class":481,"line":637},[1812],{"type":41,"tag":479,"props":1813,"children":1814},{},[1815],{"type":47,"value":1816},"    \u003CartifactId>org.osgi.service.component\u003C\u002FartifactId>\n",{"type":41,"tag":479,"props":1818,"children":1819},{"class":481,"line":646},[1820],{"type":41,"tag":479,"props":1821,"children":1822},{},[1823],{"type":47,"value":1778},{"type":41,"tag":479,"props":1825,"children":1826},{"class":481,"line":692},[1827],{"type":41,"tag":479,"props":1828,"children":1829},{},[1830],{"type":47,"value":1786},{"type":41,"tag":479,"props":1832,"children":1833},{"class":481,"line":700},[1834],{"type":41,"tag":479,"props":1835,"children":1836},{},[1837],{"type":47,"value":1794},{"type":41,"tag":479,"props":1839,"children":1840},{"class":481,"line":709},[1841],{"type":41,"tag":479,"props":1842,"children":1843},{},[1844],{"type":47,"value":1754},{"type":41,"tag":479,"props":1846,"children":1847},{"class":481,"line":1520},[1848],{"type":41,"tag":479,"props":1849,"children":1850},{},[1851],{"type":47,"value":1762},{"type":41,"tag":479,"props":1853,"children":1854},{"class":481,"line":1528},[1855],{"type":41,"tag":479,"props":1856,"children":1857},{},[1858],{"type":47,"value":1859},"    \u003CartifactId>org.osgi.service.metatype.annotations\u003C\u002FartifactId>\n",{"type":41,"tag":479,"props":1861,"children":1862},{"class":481,"line":1536},[1863],{"type":41,"tag":479,"props":1864,"children":1865},{},[1866],{"type":47,"value":1867},"    \u003Cversion>1.4.1\u003C\u002Fversion>\n",{"type":41,"tag":479,"props":1869,"children":1870},{"class":481,"line":1545},[1871],{"type":41,"tag":479,"props":1872,"children":1873},{},[1874],{"type":47,"value":1786},{"type":41,"tag":479,"props":1876,"children":1877},{"class":481,"line":1554},[1878],{"type":41,"tag":479,"props":1879,"children":1880},{},[1881],{"type":47,"value":1794},{"type":41,"tag":50,"props":1883,"children":1884},{},[1885,1890],{"type":41,"tag":99,"props":1886,"children":1887},{},[1888],{"type":47,"value":1889},"Important",{"type":47,"value":1891},": This migration skill enforces the latest stable versions:",{"type":41,"tag":91,"props":1893,"children":1894},{},[1895,1905,1915],{"type":41,"tag":95,"props":1896,"children":1897},{},[1898,1903],{"type":41,"tag":99,"props":1899,"children":1900},{},[1901],{"type":47,"value":1902},"org.osgi.service.component.annotations: 1.5.1",{"type":47,"value":1904}," (required - provides @Component, @Reference, etc.)",{"type":41,"tag":95,"props":1906,"children":1907},{},[1908,1913],{"type":41,"tag":99,"props":1909,"children":1910},{},[1911],{"type":47,"value":1912},"org.osgi.service.component: 1.5.1",{"type":47,"value":1914}," (required - provides property type annotations like @ServiceDescription, @ServiceRanking, @ServiceVendor)",{"type":41,"tag":95,"props":1916,"children":1917},{},[1918,1923],{"type":41,"tag":99,"props":1919,"children":1920},{},[1921],{"type":47,"value":1922},"org.osgi.service.metatype.annotations: 1.4.1",{"type":47,"value":1924}," (required when metatype is used)",{"type":41,"tag":50,"props":1926,"children":1927},{},[1928,1933],{"type":41,"tag":99,"props":1929,"children":1930},{},[1931],{"type":47,"value":1932},"Automatic for Sling Projects",{"type":47,"value":1934},": When Sling servlets\u002Ffilters are detected:",{"type":41,"tag":91,"props":1936,"children":1937},{},[1938],{"type":41,"tag":95,"props":1939,"children":1940},{},[1941,1946],{"type":41,"tag":99,"props":1942,"children":1943},{},[1944],{"type":47,"value":1945},"org.apache.sling.servlets.annotations: 1.2.6",{"type":47,"value":1947}," (automatically added, provides type-safe Sling annotations)",{"type":41,"tag":50,"props":1949,"children":1950},{},[1951],{"type":47,"value":1952},"These versions are required for proper OSGi R6\u002FR7 compatibility.",{"type":41,"tag":785,"props":1954,"children":1956},{"id":1955},"sling-annotations-fully-automated",[1957],{"type":47,"value":1958},"Sling Annotations (Fully Automated)",{"type":41,"tag":50,"props":1960,"children":1961},{},[1962],{"type":47,"value":1963},"Sling servlets and filters are completely automated. The migration uses type-safe Sling Servlets Annotations:",{"type":41,"tag":468,"props":1965,"children":1967},{"className":1409,"code":1966,"language":14,"meta":473,"style":473},"\u002F\u002F Before\n@SlingServlet(\n    paths = \"\u002Fbin\u002Fmyservlet\",\n    methods = {\"GET\", \"POST\"},\n    extensions = {\"html\", \"json\"}\n)\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n\n\u002F\u002F After (automatically generated)\nimport org.apache.sling.servlets.annotations.SlingServletPaths;\nimport org.osgi.service.component.annotations.Component;\nimport javax.servlet.Servlet;\n\n@Component(service = Servlet.class)\n@SlingServletPaths(value = \"\u002Fbin\u002Fmyservlet\")\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n",[1968],{"type":41,"tag":68,"props":1969,"children":1970},{"__ignoreMap":473},[1971,1979,1987,1995,2003,2011,2019,2027,2034,2041,2049,2057,2065,2073,2080,2088,2096,2103],{"type":41,"tag":479,"props":1972,"children":1973},{"class":481,"line":482},[1974],{"type":41,"tag":479,"props":1975,"children":1976},{},[1977],{"type":47,"value":1978},"\u002F\u002F Before\n",{"type":41,"tag":479,"props":1980,"children":1981},{"class":481,"line":492},[1982],{"type":41,"tag":479,"props":1983,"children":1984},{},[1985],{"type":47,"value":1986},"@SlingServlet(\n",{"type":41,"tag":479,"props":1988,"children":1989},{"class":481,"line":508},[1990],{"type":41,"tag":479,"props":1991,"children":1992},{},[1993],{"type":47,"value":1994},"    paths = \"\u002Fbin\u002Fmyservlet\",\n",{"type":41,"tag":479,"props":1996,"children":1997},{"class":481,"line":526},[1998],{"type":41,"tag":479,"props":1999,"children":2000},{},[2001],{"type":47,"value":2002},"    methods = {\"GET\", \"POST\"},\n",{"type":41,"tag":479,"props":2004,"children":2005},{"class":481,"line":560},[2006],{"type":41,"tag":479,"props":2007,"children":2008},{},[2009],{"type":47,"value":2010},"    extensions = {\"html\", \"json\"}\n",{"type":41,"tag":479,"props":2012,"children":2013},{"class":481,"line":570},[2014],{"type":41,"tag":479,"props":2015,"children":2016},{},[2017],{"type":47,"value":2018},")\n",{"type":41,"tag":479,"props":2020,"children":2021},{"class":481,"line":579},[2022],{"type":41,"tag":479,"props":2023,"children":2024},{},[2025],{"type":47,"value":2026},"public class MyServlet extends SlingAllMethodsServlet {\n",{"type":41,"tag":479,"props":2028,"children":2029},{"class":481,"line":629},[2030],{"type":41,"tag":479,"props":2031,"children":2032},{},[2033],{"type":47,"value":1486},{"type":41,"tag":479,"props":2035,"children":2036},{"class":481,"line":637},[2037],{"type":41,"tag":479,"props":2038,"children":2039},{"emptyLinePlaceholder":564},[2040],{"type":47,"value":567},{"type":41,"tag":479,"props":2042,"children":2043},{"class":481,"line":646},[2044],{"type":41,"tag":479,"props":2045,"children":2046},{},[2047],{"type":47,"value":2048},"\u002F\u002F After (automatically generated)\n",{"type":41,"tag":479,"props":2050,"children":2051},{"class":481,"line":692},[2052],{"type":41,"tag":479,"props":2053,"children":2054},{},[2055],{"type":47,"value":2056},"import org.apache.sling.servlets.annotations.SlingServletPaths;\n",{"type":41,"tag":479,"props":2058,"children":2059},{"class":481,"line":700},[2060],{"type":41,"tag":479,"props":2061,"children":2062},{},[2063],{"type":47,"value":2064},"import org.osgi.service.component.annotations.Component;\n",{"type":41,"tag":479,"props":2066,"children":2067},{"class":481,"line":709},[2068],{"type":41,"tag":479,"props":2069,"children":2070},{},[2071],{"type":47,"value":2072},"import javax.servlet.Servlet;\n",{"type":41,"tag":479,"props":2074,"children":2075},{"class":481,"line":1520},[2076],{"type":41,"tag":479,"props":2077,"children":2078},{"emptyLinePlaceholder":564},[2079],{"type":47,"value":567},{"type":41,"tag":479,"props":2081,"children":2082},{"class":481,"line":1528},[2083],{"type":41,"tag":479,"props":2084,"children":2085},{},[2086],{"type":47,"value":2087},"@Component(service = Servlet.class)\n",{"type":41,"tag":479,"props":2089,"children":2090},{"class":481,"line":1536},[2091],{"type":41,"tag":479,"props":2092,"children":2093},{},[2094],{"type":47,"value":2095},"@SlingServletPaths(value = \"\u002Fbin\u002Fmyservlet\")\n",{"type":41,"tag":479,"props":2097,"children":2098},{"class":481,"line":1545},[2099],{"type":41,"tag":479,"props":2100,"children":2101},{},[2102],{"type":47,"value":2026},{"type":41,"tag":479,"props":2104,"children":2105},{"class":481,"line":1554},[2106],{"type":41,"tag":479,"props":2107,"children":2108},{},[2109],{"type":47,"value":1486},{"type":41,"tag":50,"props":2111,"children":2112},{},[2113,2118,2120,2126],{"type":41,"tag":99,"props":2114,"children":2115},{},[2116],{"type":47,"value":2117},"Path-based servlets",{"type":47,"value":2119}," use ",{"type":41,"tag":68,"props":2121,"children":2123},{"className":2122},[],[2124],{"type":47,"value":2125},"@SlingServletPaths",{"type":47,"value":2127},":",{"type":41,"tag":468,"props":2129,"children":2131},{"className":1409,"code":2130,"language":14,"meta":473,"style":473},"@Component(service = Servlet.class)\n@SlingServletPaths(value = {\"\u002Fbin\u002Fservlet1\", \"\u002Fbin\u002Fservlet2\"})\n",[2132],{"type":41,"tag":68,"props":2133,"children":2134},{"__ignoreMap":473},[2135,2142],{"type":41,"tag":479,"props":2136,"children":2137},{"class":481,"line":482},[2138],{"type":41,"tag":479,"props":2139,"children":2140},{},[2141],{"type":47,"value":2087},{"type":41,"tag":479,"props":2143,"children":2144},{"class":481,"line":492},[2145],{"type":41,"tag":479,"props":2146,"children":2147},{},[2148],{"type":47,"value":2149},"@SlingServletPaths(value = {\"\u002Fbin\u002Fservlet1\", \"\u002Fbin\u002Fservlet2\"})\n",{"type":41,"tag":50,"props":2151,"children":2152},{},[2153,2158,2159,2165],{"type":41,"tag":99,"props":2154,"children":2155},{},[2156],{"type":47,"value":2157},"Resource-type-based servlets",{"type":47,"value":2119},{"type":41,"tag":68,"props":2160,"children":2162},{"className":2161},[],[2163],{"type":47,"value":2164},"@SlingServletResourceTypes",{"type":47,"value":2127},{"type":41,"tag":468,"props":2167,"children":2169},{"className":1409,"code":2168,"language":14,"meta":473,"style":473},"@Component(service = Servlet.class)\n@SlingServletResourceTypes(\n    resourceTypes = \"my\u002Fresource\u002Ftype\",\n    selectors = \"print\",\n    extensions = {\"html\", \"pdf\"},\n    methods = {\"GET\", \"POST\"}\n)\n",[2170],{"type":41,"tag":68,"props":2171,"children":2172},{"__ignoreMap":473},[2173,2180,2188,2196,2204,2212,2220],{"type":41,"tag":479,"props":2174,"children":2175},{"class":481,"line":482},[2176],{"type":41,"tag":479,"props":2177,"children":2178},{},[2179],{"type":47,"value":2087},{"type":41,"tag":479,"props":2181,"children":2182},{"class":481,"line":492},[2183],{"type":41,"tag":479,"props":2184,"children":2185},{},[2186],{"type":47,"value":2187},"@SlingServletResourceTypes(\n",{"type":41,"tag":479,"props":2189,"children":2190},{"class":481,"line":508},[2191],{"type":41,"tag":479,"props":2192,"children":2193},{},[2194],{"type":47,"value":2195},"    resourceTypes = \"my\u002Fresource\u002Ftype\",\n",{"type":41,"tag":479,"props":2197,"children":2198},{"class":481,"line":526},[2199],{"type":41,"tag":479,"props":2200,"children":2201},{},[2202],{"type":47,"value":2203},"    selectors = \"print\",\n",{"type":41,"tag":479,"props":2205,"children":2206},{"class":481,"line":560},[2207],{"type":41,"tag":479,"props":2208,"children":2209},{},[2210],{"type":47,"value":2211},"    extensions = {\"html\", \"pdf\"},\n",{"type":41,"tag":479,"props":2213,"children":2214},{"class":481,"line":570},[2215],{"type":41,"tag":479,"props":2216,"children":2217},{},[2218],{"type":47,"value":2219},"    methods = {\"GET\", \"POST\"}\n",{"type":41,"tag":479,"props":2221,"children":2222},{"class":481,"line":579},[2223],{"type":41,"tag":479,"props":2224,"children":2225},{},[2226],{"type":47,"value":2018},{"type":41,"tag":50,"props":2228,"children":2229},{},[2230,2235,2236,2242],{"type":41,"tag":99,"props":2231,"children":2232},{},[2233],{"type":47,"value":2234},"Filters",{"type":47,"value":2119},{"type":41,"tag":68,"props":2237,"children":2239},{"className":2238},[],[2240],{"type":47,"value":2241},"@SlingServletFilter",{"type":47,"value":2127},{"type":41,"tag":468,"props":2244,"children":2246},{"className":1409,"code":2245,"language":14,"meta":473,"style":473},"@Component(service = Filter.class)\n@SlingServletFilter(\n    scope = SlingServletFilterScope.REQUEST,\n    order = -700,\n    pattern = \"\u002Fcontent\u002F.*\"\n)\n",[2247],{"type":41,"tag":68,"props":2248,"children":2249},{"__ignoreMap":473},[2250,2258,2266,2274,2282,2290],{"type":41,"tag":479,"props":2251,"children":2252},{"class":481,"line":482},[2253],{"type":41,"tag":479,"props":2254,"children":2255},{},[2256],{"type":47,"value":2257},"@Component(service = Filter.class)\n",{"type":41,"tag":479,"props":2259,"children":2260},{"class":481,"line":492},[2261],{"type":41,"tag":479,"props":2262,"children":2263},{},[2264],{"type":47,"value":2265},"@SlingServletFilter(\n",{"type":41,"tag":479,"props":2267,"children":2268},{"class":481,"line":508},[2269],{"type":41,"tag":479,"props":2270,"children":2271},{},[2272],{"type":47,"value":2273},"    scope = SlingServletFilterScope.REQUEST,\n",{"type":41,"tag":479,"props":2275,"children":2276},{"class":481,"line":526},[2277],{"type":41,"tag":479,"props":2278,"children":2279},{},[2280],{"type":47,"value":2281},"    order = -700,\n",{"type":41,"tag":479,"props":2283,"children":2284},{"class":481,"line":560},[2285],{"type":41,"tag":479,"props":2286,"children":2287},{},[2288],{"type":47,"value":2289},"    pattern = \"\u002Fcontent\u002F.*\"\n",{"type":41,"tag":479,"props":2291,"children":2292},{"class":481,"line":570},[2293],{"type":41,"tag":479,"props":2294,"children":2295},{},[2296],{"type":47,"value":2018},{"type":41,"tag":50,"props":2298,"children":2299},{},[2300],{"type":47,"value":2301},"The migration automatically:",{"type":41,"tag":91,"props":2303,"children":2304},{},[2305,2310,2323,2328],{"type":41,"tag":95,"props":2306,"children":2307},{},[2308],{"type":47,"value":2309},"Detects Sling servlet\u002Ffilter usage in your Java files",{"type":41,"tag":95,"props":2311,"children":2312},{},[2313,2315,2321],{"type":47,"value":2314},"Adds the ",{"type":41,"tag":68,"props":2316,"children":2318},{"className":2317},[],[2319],{"type":47,"value":2320},"org.apache.sling.servlets.annotations:1.2.6",{"type":47,"value":2322}," dependency to your POM",{"type":41,"tag":95,"props":2324,"children":2325},{},[2326],{"type":47,"value":2327},"Transforms annotations to use the type-safe Sling Servlets Annotations format",{"type":41,"tag":95,"props":2329,"children":2330},{},[2331],{"type":47,"value":2332},"Updates all necessary imports",{"type":41,"tag":50,"props":2334,"children":2335},{},[2336,2338,2344],{"type":47,"value":2337},"See ",{"type":41,"tag":2339,"props":2340,"children":2342},"a",{"href":2341},"references\u002Fannotation-mappings.md",[2343],{"type":47,"value":2341},{"type":47,"value":2345}," for detailed examples of all Sling annotation transformations.",{"type":41,"tag":451,"props":2347,"children":2349},{"id":2348},"step-5-build-and-test",[2350],{"type":47,"value":2351},"Step 5: Build and Test",{"type":41,"tag":468,"props":2353,"children":2355},{"className":470,"code":2354,"language":472,"meta":473,"style":473},"# Clean and build\nmvn clean install\n\n# Run tests\nmvn test\n\n# Verify bundle activation\n# The migration scripts include validation to catch common issues\n",[2356],{"type":41,"tag":68,"props":2357,"children":2358},{"__ignoreMap":473},[2359,2367,2385,2392,2400,2412,2419,2427],{"type":41,"tag":479,"props":2360,"children":2361},{"class":481,"line":482},[2362],{"type":41,"tag":479,"props":2363,"children":2364},{"style":486},[2365],{"type":47,"value":2366},"# Clean and build\n",{"type":41,"tag":479,"props":2368,"children":2369},{"class":481,"line":492},[2370,2375,2380],{"type":41,"tag":479,"props":2371,"children":2372},{"style":496},[2373],{"type":47,"value":2374},"mvn",{"type":41,"tag":479,"props":2376,"children":2377},{"style":502},[2378],{"type":47,"value":2379}," clean",{"type":41,"tag":479,"props":2381,"children":2382},{"style":502},[2383],{"type":47,"value":2384}," install\n",{"type":41,"tag":479,"props":2386,"children":2387},{"class":481,"line":508},[2388],{"type":41,"tag":479,"props":2389,"children":2390},{"emptyLinePlaceholder":564},[2391],{"type":47,"value":567},{"type":41,"tag":479,"props":2393,"children":2394},{"class":481,"line":526},[2395],{"type":41,"tag":479,"props":2396,"children":2397},{"style":486},[2398],{"type":47,"value":2399},"# Run tests\n",{"type":41,"tag":479,"props":2401,"children":2402},{"class":481,"line":560},[2403,2407],{"type":41,"tag":479,"props":2404,"children":2405},{"style":496},[2406],{"type":47,"value":2374},{"type":41,"tag":479,"props":2408,"children":2409},{"style":502},[2410],{"type":47,"value":2411}," test\n",{"type":41,"tag":479,"props":2413,"children":2414},{"class":481,"line":570},[2415],{"type":41,"tag":479,"props":2416,"children":2417},{"emptyLinePlaceholder":564},[2418],{"type":47,"value":567},{"type":41,"tag":479,"props":2420,"children":2421},{"class":481,"line":579},[2422],{"type":41,"tag":479,"props":2423,"children":2424},{"style":486},[2425],{"type":47,"value":2426},"# Verify bundle activation\n",{"type":41,"tag":479,"props":2428,"children":2429},{"class":481,"line":629},[2430],{"type":41,"tag":479,"props":2431,"children":2432},{"style":486},[2433],{"type":47,"value":2434},"# The migration scripts include validation to catch common issues\n",{"type":41,"tag":451,"props":2436,"children":2438},{"id":2437},"step-6-run-validation",[2439],{"type":47,"value":2440},"Step 6: Run Validation",{"type":41,"tag":468,"props":2442,"children":2444},{"className":470,"code":2443,"language":472,"meta":473,"style":473},"# Validate Java migrations\npython3 scripts\u002Fmigrate_annotations.py \u002Fpath\u002Fto\u002Fsrc --validate\n\n# Validate POM migrations\npython3 scripts\u002Fmigrate_pom.py \u002Fpath\u002Fto\u002Fproject --validate\n\n# Run comprehensive test suite\nbash scripts\u002Ftests\u002Frun_tests.sh\n",[2445],{"type":41,"tag":68,"props":2446,"children":2447},{"__ignoreMap":473},[2448,2456,2475,2482,2490,2509,2516,2524],{"type":41,"tag":479,"props":2449,"children":2450},{"class":481,"line":482},[2451],{"type":41,"tag":479,"props":2452,"children":2453},{"style":486},[2454],{"type":47,"value":2455},"# Validate Java migrations\n",{"type":41,"tag":479,"props":2457,"children":2458},{"class":481,"line":492},[2459,2463,2467,2471],{"type":41,"tag":479,"props":2460,"children":2461},{"style":496},[2462],{"type":47,"value":813},{"type":41,"tag":479,"props":2464,"children":2465},{"style":502},[2466],{"type":47,"value":818},{"type":41,"tag":479,"props":2468,"children":2469},{"style":502},[2470],{"type":47,"value":823},{"type":41,"tag":479,"props":2472,"children":2473},{"style":502},[2474],{"type":47,"value":863},{"type":41,"tag":479,"props":2476,"children":2477},{"class":481,"line":508},[2478],{"type":41,"tag":479,"props":2479,"children":2480},{"emptyLinePlaceholder":564},[2481],{"type":47,"value":567},{"type":41,"tag":479,"props":2483,"children":2484},{"class":481,"line":526},[2485],{"type":41,"tag":479,"props":2486,"children":2487},{"style":486},[2488],{"type":47,"value":2489},"# Validate POM migrations\n",{"type":41,"tag":479,"props":2491,"children":2492},{"class":481,"line":560},[2493,2497,2501,2505],{"type":41,"tag":479,"props":2494,"children":2495},{"style":496},[2496],{"type":47,"value":813},{"type":41,"tag":479,"props":2498,"children":2499},{"style":502},[2500],{"type":47,"value":1099},{"type":41,"tag":479,"props":2502,"children":2503},{"style":502},[2504],{"type":47,"value":1104},{"type":41,"tag":479,"props":2506,"children":2507},{"style":502},[2508],{"type":47,"value":863},{"type":41,"tag":479,"props":2510,"children":2511},{"class":481,"line":570},[2512],{"type":41,"tag":479,"props":2513,"children":2514},{"emptyLinePlaceholder":564},[2515],{"type":47,"value":567},{"type":41,"tag":479,"props":2517,"children":2518},{"class":481,"line":579},[2519],{"type":41,"tag":479,"props":2520,"children":2521},{"style":486},[2522],{"type":47,"value":2523},"# Run comprehensive test suite\n",{"type":41,"tag":479,"props":2525,"children":2526},{"class":481,"line":629},[2527,2531],{"type":41,"tag":479,"props":2528,"children":2529},{"style":496},[2530],{"type":47,"value":472},{"type":41,"tag":479,"props":2532,"children":2533},{"style":502},[2534],{"type":47,"value":2535}," scripts\u002Ftests\u002Frun_tests.sh\n",{"type":41,"tag":50,"props":2537,"children":2538},{},[2539,2544],{"type":41,"tag":99,"props":2540,"children":2541},{},[2542],{"type":47,"value":2543},"✅ Basic migration complete!",{"type":47,"value":2545}," If all tests pass, proceed to Step 7 for optional constructor injection optimization.",{"type":41,"tag":2547,"props":2548,"children":2549},"hr",{},[],{"type":41,"tag":56,"props":2551,"children":2553},{"id":2552},"optional-post-migration-optimization",[2554],{"type":47,"value":2555},"✨ Optional Post-Migration Optimization",{"type":41,"tag":50,"props":2557,"children":2558},{},[2559,2561,2566],{"type":47,"value":2560},"Once the basic migration (Steps 1-6) is complete and all tests pass, consider ",{"type":41,"tag":99,"props":2562,"children":2563},{},[2564],{"type":47,"value":2565},"Step 7",{"type":47,"value":2567}," below to further modernize your code with constructor injection.",{"type":41,"tag":2547,"props":2569,"children":2570},{},[],{"type":41,"tag":451,"props":2572,"children":2574},{"id":2573},"step-7-optimize-with-constructor-injection-automated-optional",[2575],{"type":47,"value":2576},"Step 7: Optimize with Constructor Injection (Automated, Optional)",{"type":41,"tag":50,"props":2578,"children":2579},{},[2580,2585],{"type":41,"tag":99,"props":2581,"children":2582},{},[2583],{"type":47,"value":2584},"⚠️ IMPORTANT",{"type":47,"value":2586},": Run this step AFTER completing Steps 1-6 and ensuring all tests pass.",{"type":41,"tag":50,"props":2588,"children":2589},{},[2590,2592,2597],{"type":47,"value":2591},"Automatically optimize your code with modern OSGi best practices using ",{"type":41,"tag":99,"props":2593,"children":2594},{},[2595],{"type":47,"value":2596},"constructor injection",{"type":47,"value":2598},". This step is optional but highly recommended for cleaner, more maintainable code.",{"type":41,"tag":50,"props":2600,"children":2601},{},[2602,2607,2609,2615],{"type":41,"tag":99,"props":2603,"children":2604},{},[2605],{"type":47,"value":2606},"NEW",{"type":47,"value":2608},": This step is now fully automated using the ",{"type":41,"tag":68,"props":2610,"children":2612},{"className":2611},[],[2613],{"type":47,"value":2614},"migrate_constructor_injection.py",{"type":47,"value":2616}," script!",{"type":41,"tag":785,"props":2618,"children":2620},{"id":2619},"quick-start-run-the-migration",[2621],{"type":47,"value":2622},"Quick Start - Run the Migration",{"type":41,"tag":468,"props":2624,"children":2626},{"className":470,"code":2625,"language":472,"meta":473,"style":473},"# Preview changes (dry-run) - RECOMMENDED FIRST\npython3 scripts\u002Fmigrate_constructor_injection.py \u002Fpath\u002Fto\u002Fsrc --dry-run\n\n# Apply migration with validation\npython3 scripts\u002Fmigrate_constructor_injection.py \u002Fpath\u002Fto\u002Fsrc --validate\n\n# Single file migration\npython3 scripts\u002Fmigrate_constructor_injection.py \u002Fpath\u002Fto\u002FMyService.java\n\n# Tip: Always commit to git before running\ngit add . && git commit -m \"Pre-constructor-injection snapshot\"\n",[2627],{"type":41,"tag":68,"props":2628,"children":2629},{"__ignoreMap":473},[2630,2638,2658,2665,2673,2692,2699,2707,2723,2730,2738],{"type":41,"tag":479,"props":2631,"children":2632},{"class":481,"line":482},[2633],{"type":41,"tag":479,"props":2634,"children":2635},{"style":486},[2636],{"type":47,"value":2637},"# Preview changes (dry-run) - RECOMMENDED FIRST\n",{"type":41,"tag":479,"props":2639,"children":2640},{"class":481,"line":492},[2641,2645,2650,2654],{"type":41,"tag":479,"props":2642,"children":2643},{"style":496},[2644],{"type":47,"value":813},{"type":41,"tag":479,"props":2646,"children":2647},{"style":502},[2648],{"type":47,"value":2649}," scripts\u002Fmigrate_constructor_injection.py",{"type":41,"tag":479,"props":2651,"children":2652},{"style":502},[2653],{"type":47,"value":823},{"type":41,"tag":479,"props":2655,"children":2656},{"style":502},[2657],{"type":47,"value":828},{"type":41,"tag":479,"props":2659,"children":2660},{"class":481,"line":508},[2661],{"type":41,"tag":479,"props":2662,"children":2663},{"emptyLinePlaceholder":564},[2664],{"type":47,"value":567},{"type":41,"tag":479,"props":2666,"children":2667},{"class":481,"line":526},[2668],{"type":41,"tag":479,"props":2669,"children":2670},{"style":486},[2671],{"type":47,"value":2672},"# Apply migration with validation\n",{"type":41,"tag":479,"props":2674,"children":2675},{"class":481,"line":560},[2676,2680,2684,2688],{"type":41,"tag":479,"props":2677,"children":2678},{"style":496},[2679],{"type":47,"value":813},{"type":41,"tag":479,"props":2681,"children":2682},{"style":502},[2683],{"type":47,"value":2649},{"type":41,"tag":479,"props":2685,"children":2686},{"style":502},[2687],{"type":47,"value":823},{"type":41,"tag":479,"props":2689,"children":2690},{"style":502},[2691],{"type":47,"value":863},{"type":41,"tag":479,"props":2693,"children":2694},{"class":481,"line":570},[2695],{"type":41,"tag":479,"props":2696,"children":2697},{"emptyLinePlaceholder":564},[2698],{"type":47,"value":567},{"type":41,"tag":479,"props":2700,"children":2701},{"class":481,"line":579},[2702],{"type":41,"tag":479,"props":2703,"children":2704},{"style":486},[2705],{"type":47,"value":2706},"# Single file migration\n",{"type":41,"tag":479,"props":2708,"children":2709},{"class":481,"line":629},[2710,2714,2718],{"type":41,"tag":479,"props":2711,"children":2712},{"style":496},[2713],{"type":47,"value":813},{"type":41,"tag":479,"props":2715,"children":2716},{"style":502},[2717],{"type":47,"value":2649},{"type":41,"tag":479,"props":2719,"children":2720},{"style":502},[2721],{"type":47,"value":2722}," \u002Fpath\u002Fto\u002FMyService.java\n",{"type":41,"tag":479,"props":2724,"children":2725},{"class":481,"line":637},[2726],{"type":41,"tag":479,"props":2727,"children":2728},{"emptyLinePlaceholder":564},[2729],{"type":47,"value":567},{"type":41,"tag":479,"props":2731,"children":2732},{"class":481,"line":646},[2733],{"type":41,"tag":479,"props":2734,"children":2735},{"style":486},[2736],{"type":47,"value":2737},"# Tip: Always commit to git before running\n",{"type":41,"tag":479,"props":2739,"children":2740},{"class":481,"line":692},[2741,2745,2749,2753,2757,2761,2765,2769,2773,2778],{"type":41,"tag":479,"props":2742,"children":2743},{"style":496},[2744],{"type":47,"value":499},{"type":41,"tag":479,"props":2746,"children":2747},{"style":502},[2748],{"type":47,"value":518},{"type":41,"tag":479,"props":2750,"children":2751},{"style":502},[2752],{"type":47,"value":752},{"type":41,"tag":479,"props":2754,"children":2755},{"style":544},[2756],{"type":47,"value":898},{"type":41,"tag":479,"props":2758,"children":2759},{"style":496},[2760],{"type":47,"value":903},{"type":41,"tag":479,"props":2762,"children":2763},{"style":502},[2764],{"type":47,"value":536},{"type":41,"tag":479,"props":2766,"children":2767},{"style":502},[2768],{"type":47,"value":541},{"type":41,"tag":479,"props":2770,"children":2771},{"style":544},[2772],{"type":47,"value":547},{"type":41,"tag":479,"props":2774,"children":2775},{"style":502},[2776],{"type":47,"value":2777},"Pre-constructor-injection snapshot",{"type":41,"tag":479,"props":2779,"children":2780},{"style":544},[2781],{"type":47,"value":557},{"type":41,"tag":785,"props":2783,"children":2785},{"id":2784},"benefits-of-constructor-injection",[2786],{"type":47,"value":2787},"Benefits of Constructor Injection",{"type":41,"tag":91,"props":2789,"children":2790},{},[2791,2809,2820,2831,2842],{"type":41,"tag":95,"props":2792,"children":2793},{},[2794,2795,2800,2802,2807],{"type":47,"value":1652},{"type":41,"tag":99,"props":2796,"children":2797},{},[2798],{"type":47,"value":2799},"Immutability",{"type":47,"value":2801},": Dependencies declared as ",{"type":41,"tag":68,"props":2803,"children":2805},{"className":2804},[],[2806],{"type":47,"value":298},{"type":47,"value":2808}," fields",{"type":41,"tag":95,"props":2810,"children":2811},{},[2812,2813,2818],{"type":47,"value":1652},{"type":41,"tag":99,"props":2814,"children":2815},{},[2816],{"type":47,"value":2817},"Explicit Dependencies",{"type":47,"value":2819},": All dependencies visible in constructor signature",{"type":41,"tag":95,"props":2821,"children":2822},{},[2823,2824,2829],{"type":47,"value":1652},{"type":41,"tag":99,"props":2825,"children":2826},{},[2827],{"type":47,"value":2828},"Thread Safety",{"type":47,"value":2830},": Immutable references eliminate race conditions",{"type":41,"tag":95,"props":2832,"children":2833},{},[2834,2835,2840],{"type":47,"value":1652},{"type":41,"tag":99,"props":2836,"children":2837},{},[2838],{"type":47,"value":2839},"Testability",{"type":47,"value":2841},": Easier to mock dependencies in unit tests",{"type":41,"tag":95,"props":2843,"children":2844},{},[2845,2846,2851],{"type":47,"value":1652},{"type":41,"tag":99,"props":2847,"children":2848},{},[2849],{"type":47,"value":2850},"Modern Best Practice",{"type":47,"value":2852},": Aligned with OSGi R7\u002FR8 recommendations",{"type":41,"tag":785,"props":2854,"children":2856},{"id":2855},"_7a-constructor-injection-for-configurations",[2857],{"type":47,"value":2858},"7a. Constructor Injection for Configurations",{"type":41,"tag":50,"props":2860,"children":2861},{},[2862,2864,2869],{"type":47,"value":2863},"Instead of using ",{"type":41,"tag":68,"props":2865,"children":2867},{"className":2866},[],[2868],{"type":47,"value":1046},{"type":47,"value":2870}," methods to receive configuration, inject it directly in the constructor:",{"type":41,"tag":468,"props":2872,"children":2874},{"className":1409,"code":2873,"language":14,"meta":473,"style":473},"\u002F\u002F After basic migration (Step 2)\n@Component\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\")\n        int timeout() default 30;\n\n        @AttributeDefinition(name = \"Max Retries\")\n        int maxRetries() default 3;\n    }\n\n    private int timeout;\n    private int maxRetries;\n\n    @Activate\n    private void activate(Config config) {\n        this.timeout = config.timeout();\n        this.maxRetries = config.maxRetries();\n    }\n}\n\n\u002F\u002F After optimization (Step 7)\n@Component\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\")\n        int timeout() default 30;\n\n        @AttributeDefinition(name = \"Max Retries\")\n        int maxRetries() default 3;\n    }\n\n    private final int timeout;\n    private final int maxRetries;\n\n    @Activate\n    public MyService(Config config) {\n        this.timeout = config.timeout();\n        this.maxRetries = config.maxRetries();\n    }\n}\n",[2875],{"type":41,"tag":68,"props":2876,"children":2877},{"__ignoreMap":473},[2878,2886,2893,2900,2907,2914,2922,2929,2937,2944,2951,2959,2967,2974,2981,2989,2997,3004,3011,3018,3026,3034,3041,3048,3055,3063,3070,3077,3085,3093,3101,3109,3116,3124,3132,3140,3148,3156,3164,3173,3182,3190,3198,3207,3215,3223,3231],{"type":41,"tag":479,"props":2879,"children":2880},{"class":481,"line":482},[2881],{"type":41,"tag":479,"props":2882,"children":2883},{},[2884],{"type":47,"value":2885},"\u002F\u002F After basic migration (Step 2)\n",{"type":41,"tag":479,"props":2887,"children":2888},{"class":481,"line":492},[2889],{"type":41,"tag":479,"props":2890,"children":2891},{},[2892],{"type":47,"value":1509},{"type":41,"tag":479,"props":2894,"children":2895},{"class":481,"line":508},[2896],{"type":41,"tag":479,"props":2897,"children":2898},{},[2899],{"type":47,"value":1517},{"type":41,"tag":479,"props":2901,"children":2902},{"class":481,"line":526},[2903],{"type":41,"tag":479,"props":2904,"children":2905},{},[2906],{"type":47,"value":1446},{"type":41,"tag":479,"props":2908,"children":2909},{"class":481,"line":560},[2910],{"type":41,"tag":479,"props":2911,"children":2912},{"emptyLinePlaceholder":564},[2913],{"type":47,"value":567},{"type":41,"tag":479,"props":2915,"children":2916},{"class":481,"line":570},[2917],{"type":41,"tag":479,"props":2918,"children":2919},{},[2920],{"type":47,"value":2921},"    @ObjectClassDefinition(name = \"My Service\")\n",{"type":41,"tag":479,"props":2923,"children":2924},{"class":481,"line":579},[2925],{"type":41,"tag":479,"props":2926,"children":2927},{},[2928],{"type":47,"value":1551},{"type":41,"tag":479,"props":2930,"children":2931},{"class":481,"line":629},[2932],{"type":41,"tag":479,"props":2933,"children":2934},{},[2935],{"type":47,"value":2936},"        @AttributeDefinition(name = \"Timeout\")\n",{"type":41,"tag":479,"props":2938,"children":2939},{"class":481,"line":637},[2940],{"type":41,"tag":479,"props":2941,"children":2942},{},[2943],{"type":47,"value":1569},{"type":41,"tag":479,"props":2945,"children":2946},{"class":481,"line":646},[2947],{"type":41,"tag":479,"props":2948,"children":2949},{"emptyLinePlaceholder":564},[2950],{"type":47,"value":567},{"type":41,"tag":479,"props":2952,"children":2953},{"class":481,"line":692},[2954],{"type":41,"tag":479,"props":2955,"children":2956},{},[2957],{"type":47,"value":2958},"        @AttributeDefinition(name = \"Max Retries\")\n",{"type":41,"tag":479,"props":2960,"children":2961},{"class":481,"line":700},[2962],{"type":41,"tag":479,"props":2963,"children":2964},{},[2965],{"type":47,"value":2966},"        int maxRetries() default 3;\n",{"type":41,"tag":479,"props":2968,"children":2969},{"class":481,"line":709},[2970],{"type":41,"tag":479,"props":2971,"children":2972},{},[2973],{"type":47,"value":1478},{"type":41,"tag":479,"props":2975,"children":2976},{"class":481,"line":1520},[2977],{"type":41,"tag":479,"props":2978,"children":2979},{"emptyLinePlaceholder":564},[2980],{"type":47,"value":567},{"type":41,"tag":479,"props":2982,"children":2983},{"class":481,"line":1528},[2984],{"type":41,"tag":479,"props":2985,"children":2986},{},[2987],{"type":47,"value":2988},"    private int timeout;\n",{"type":41,"tag":479,"props":2990,"children":2991},{"class":481,"line":1536},[2992],{"type":41,"tag":479,"props":2993,"children":2994},{},[2995],{"type":47,"value":2996},"    private int maxRetries;\n",{"type":41,"tag":479,"props":2998,"children":2999},{"class":481,"line":1545},[3000],{"type":41,"tag":479,"props":3001,"children":3002},{"emptyLinePlaceholder":564},[3003],{"type":47,"value":567},{"type":41,"tag":479,"props":3005,"children":3006},{"class":481,"line":1554},[3007],{"type":41,"tag":479,"props":3008,"children":3009},{},[3010],{"type":47,"value":1454},{"type":41,"tag":479,"props":3012,"children":3013},{"class":481,"line":1563},[3014],{"type":41,"tag":479,"props":3015,"children":3016},{},[3017],{"type":47,"value":1602},{"type":41,"tag":479,"props":3019,"children":3020},{"class":481,"line":1572},[3021],{"type":41,"tag":479,"props":3022,"children":3023},{},[3024],{"type":47,"value":3025},"        this.timeout = config.timeout();\n",{"type":41,"tag":479,"props":3027,"children":3028},{"class":481,"line":1580},[3029],{"type":41,"tag":479,"props":3030,"children":3031},{},[3032],{"type":47,"value":3033},"        this.maxRetries = config.maxRetries();\n",{"type":41,"tag":479,"props":3035,"children":3036},{"class":481,"line":1588},[3037],{"type":41,"tag":479,"props":3038,"children":3039},{},[3040],{"type":47,"value":1478},{"type":41,"tag":479,"props":3042,"children":3043},{"class":481,"line":1596},[3044],{"type":41,"tag":479,"props":3045,"children":3046},{},[3047],{"type":47,"value":1486},{"type":41,"tag":479,"props":3049,"children":3050},{"class":481,"line":1605},[3051],{"type":41,"tag":479,"props":3052,"children":3053},{"emptyLinePlaceholder":564},[3054],{"type":47,"value":567},{"type":41,"tag":479,"props":3056,"children":3057},{"class":481,"line":1614},[3058],{"type":41,"tag":479,"props":3059,"children":3060},{},[3061],{"type":47,"value":3062},"\u002F\u002F After optimization (Step 7)\n",{"type":41,"tag":479,"props":3064,"children":3065},{"class":481,"line":1623},[3066],{"type":41,"tag":479,"props":3067,"children":3068},{},[3069],{"type":47,"value":1509},{"type":41,"tag":479,"props":3071,"children":3072},{"class":481,"line":1631},[3073],{"type":41,"tag":479,"props":3074,"children":3075},{},[3076],{"type":47,"value":1517},{"type":41,"tag":479,"props":3078,"children":3080},{"class":481,"line":3079},28,[3081],{"type":41,"tag":479,"props":3082,"children":3083},{},[3084],{"type":47,"value":1446},{"type":41,"tag":479,"props":3086,"children":3088},{"class":481,"line":3087},29,[3089],{"type":41,"tag":479,"props":3090,"children":3091},{"emptyLinePlaceholder":564},[3092],{"type":47,"value":567},{"type":41,"tag":479,"props":3094,"children":3096},{"class":481,"line":3095},30,[3097],{"type":41,"tag":479,"props":3098,"children":3099},{},[3100],{"type":47,"value":2921},{"type":41,"tag":479,"props":3102,"children":3104},{"class":481,"line":3103},31,[3105],{"type":41,"tag":479,"props":3106,"children":3107},{},[3108],{"type":47,"value":1551},{"type":41,"tag":479,"props":3110,"children":3111},{"class":481,"line":26},[3112],{"type":41,"tag":479,"props":3113,"children":3114},{},[3115],{"type":47,"value":2936},{"type":41,"tag":479,"props":3117,"children":3119},{"class":481,"line":3118},33,[3120],{"type":41,"tag":479,"props":3121,"children":3122},{},[3123],{"type":47,"value":1569},{"type":41,"tag":479,"props":3125,"children":3127},{"class":481,"line":3126},34,[3128],{"type":41,"tag":479,"props":3129,"children":3130},{"emptyLinePlaceholder":564},[3131],{"type":47,"value":567},{"type":41,"tag":479,"props":3133,"children":3135},{"class":481,"line":3134},35,[3136],{"type":41,"tag":479,"props":3137,"children":3138},{},[3139],{"type":47,"value":2958},{"type":41,"tag":479,"props":3141,"children":3143},{"class":481,"line":3142},36,[3144],{"type":41,"tag":479,"props":3145,"children":3146},{},[3147],{"type":47,"value":2966},{"type":41,"tag":479,"props":3149,"children":3151},{"class":481,"line":3150},37,[3152],{"type":41,"tag":479,"props":3153,"children":3154},{},[3155],{"type":47,"value":1478},{"type":41,"tag":479,"props":3157,"children":3159},{"class":481,"line":3158},38,[3160],{"type":41,"tag":479,"props":3161,"children":3162},{"emptyLinePlaceholder":564},[3163],{"type":47,"value":567},{"type":41,"tag":479,"props":3165,"children":3167},{"class":481,"line":3166},39,[3168],{"type":41,"tag":479,"props":3169,"children":3170},{},[3171],{"type":47,"value":3172},"    private final int timeout;\n",{"type":41,"tag":479,"props":3174,"children":3176},{"class":481,"line":3175},40,[3177],{"type":41,"tag":479,"props":3178,"children":3179},{},[3180],{"type":47,"value":3181},"    private final int maxRetries;\n",{"type":41,"tag":479,"props":3183,"children":3185},{"class":481,"line":3184},41,[3186],{"type":41,"tag":479,"props":3187,"children":3188},{"emptyLinePlaceholder":564},[3189],{"type":47,"value":567},{"type":41,"tag":479,"props":3191,"children":3193},{"class":481,"line":3192},42,[3194],{"type":41,"tag":479,"props":3195,"children":3196},{},[3197],{"type":47,"value":1454},{"type":41,"tag":479,"props":3199,"children":3201},{"class":481,"line":3200},43,[3202],{"type":41,"tag":479,"props":3203,"children":3204},{},[3205],{"type":47,"value":3206},"    public MyService(Config config) {\n",{"type":41,"tag":479,"props":3208,"children":3210},{"class":481,"line":3209},44,[3211],{"type":41,"tag":479,"props":3212,"children":3213},{},[3214],{"type":47,"value":3025},{"type":41,"tag":479,"props":3216,"children":3218},{"class":481,"line":3217},45,[3219],{"type":41,"tag":479,"props":3220,"children":3221},{},[3222],{"type":47,"value":3033},{"type":41,"tag":479,"props":3224,"children":3226},{"class":481,"line":3225},46,[3227],{"type":41,"tag":479,"props":3228,"children":3229},{},[3230],{"type":47,"value":1478},{"type":41,"tag":479,"props":3232,"children":3234},{"class":481,"line":3233},47,[3235],{"type":41,"tag":479,"props":3236,"children":3237},{},[3238],{"type":47,"value":1486},{"type":41,"tag":50,"props":3240,"children":3241},{},[3242],{"type":41,"tag":99,"props":3243,"children":3244},{},[3245],{"type":47,"value":3246},"Key changes:",{"type":41,"tag":91,"props":3248,"children":3249},{},[3250,3263,3275,3287],{"type":41,"tag":95,"props":3251,"children":3252},{},[3253,3255,3261],{"type":47,"value":3254},"Constructor is now ",{"type":41,"tag":68,"props":3256,"children":3258},{"className":3257},[],[3259],{"type":47,"value":3260},"public",{"type":47,"value":3262}," (OSGi requirement for constructor injection)",{"type":41,"tag":95,"props":3264,"children":3265},{},[3266,3268,3273],{"type":47,"value":3267},"Configuration fields are ",{"type":41,"tag":68,"props":3269,"children":3271},{"className":3270},[],[3272],{"type":47,"value":298},{"type":47,"value":3274}," (immutable)",{"type":41,"tag":95,"props":3276,"children":3277},{},[3278,3280,3285],{"type":47,"value":3279},"No separate ",{"type":41,"tag":68,"props":3281,"children":3283},{"className":3282},[],[3284],{"type":47,"value":1046},{"type":47,"value":3286}," method needed",{"type":41,"tag":95,"props":3288,"children":3289},{},[3290],{"type":47,"value":3291},"Configuration is available immediately upon construction",{"type":41,"tag":785,"props":3293,"children":3295},{"id":3294},"_7b-constructor-injection-for-unary-static-mandatory-references",[3296],{"type":47,"value":3297},"7b. Constructor Injection for Unary Static Mandatory References",{"type":41,"tag":50,"props":3299,"children":3300},{},[3301],{"type":47,"value":3302},"For references that are:",{"type":41,"tag":91,"props":3304,"children":3305},{},[3306,3316,3326],{"type":41,"tag":95,"props":3307,"children":3308},{},[3309,3314],{"type":41,"tag":99,"props":3310,"children":3311},{},[3312],{"type":47,"value":3313},"Mandatory",{"type":47,"value":3315}," (not optional)",{"type":41,"tag":95,"props":3317,"children":3318},{},[3319,3324],{"type":41,"tag":99,"props":3320,"children":3321},{},[3322],{"type":47,"value":3323},"Static",{"type":47,"value":3325}," (not dynamic)",{"type":41,"tag":95,"props":3327,"children":3328},{},[3329,3334],{"type":41,"tag":99,"props":3330,"children":3331},{},[3332],{"type":47,"value":3333},"Unary",{"type":47,"value":3335}," (single reference, not multiple)",{"type":41,"tag":50,"props":3337,"children":3338},{},[3339],{"type":47,"value":3340},"Use constructor injection to make dependencies explicit and immutable:",{"type":41,"tag":468,"props":3342,"children":3344},{"className":1409,"code":3343,"language":14,"meta":473,"style":473},"\u002F\u002F After basic migration (Step 2) - Field injection\n@Component(service = MyService.class)\npublic class MyService {\n\n    @Reference\n    private ResourceResolverFactory resolverFactory;\n\n    @Reference\n    private SlingRepository repository;\n\n    @Reference(cardinality = ReferenceCardinality.OPTIONAL)\n    private ConfigurationAdmin configAdmin;  \u002F\u002F Optional - keep as field\n\n    public void doSomething() {\n        \u002F\u002F Use resolverFactory and repository\n    }\n}\n\n\u002F\u002F After optimization (Step 7) - Constructor injection for mandatory references\n@Component(service = MyService.class)\npublic class MyService {\n\n    private final ResourceResolverFactory resolverFactory;\n    private final SlingRepository repository;\n\n    \u002F\u002F Optional reference stays as field injection\n    @Reference(cardinality = ReferenceCardinality.OPTIONAL)\n    private ConfigurationAdmin configAdmin;\n\n    @Activate\n    public MyService(\n        @Reference ResourceResolverFactory resolverFactory,\n        @Reference SlingRepository repository\n    ) {\n        this.resolverFactory = resolverFactory;\n        this.repository = repository;\n    }\n\n    public void doSomething() {\n        \u002F\u002F Use resolverFactory and repository (guaranteed non-null)\n    }\n}\n",[3345],{"type":41,"tag":68,"props":3346,"children":3347},{"__ignoreMap":473},[3348,3356,3364,3371,3378,3386,3394,3401,3408,3416,3423,3431,3439,3446,3454,3462,3469,3476,3483,3491,3498,3505,3512,3520,3528,3535,3543,3550,3558,3565,3572,3580,3588,3596,3604,3612,3620,3627,3634,3641,3649,3656],{"type":41,"tag":479,"props":3349,"children":3350},{"class":481,"line":482},[3351],{"type":41,"tag":479,"props":3352,"children":3353},{},[3354],{"type":47,"value":3355},"\u002F\u002F After basic migration (Step 2) - Field injection\n",{"type":41,"tag":479,"props":3357,"children":3358},{"class":481,"line":492},[3359],{"type":41,"tag":479,"props":3360,"children":3361},{},[3362],{"type":47,"value":3363},"@Component(service = MyService.class)\n",{"type":41,"tag":479,"props":3365,"children":3366},{"class":481,"line":508},[3367],{"type":41,"tag":479,"props":3368,"children":3369},{},[3370],{"type":47,"value":1446},{"type":41,"tag":479,"props":3372,"children":3373},{"class":481,"line":526},[3374],{"type":41,"tag":479,"props":3375,"children":3376},{"emptyLinePlaceholder":564},[3377],{"type":47,"value":567},{"type":41,"tag":479,"props":3379,"children":3380},{"class":481,"line":560},[3381],{"type":41,"tag":479,"props":3382,"children":3383},{},[3384],{"type":47,"value":3385},"    @Reference\n",{"type":41,"tag":479,"props":3387,"children":3388},{"class":481,"line":570},[3389],{"type":41,"tag":479,"props":3390,"children":3391},{},[3392],{"type":47,"value":3393},"    private ResourceResolverFactory resolverFactory;\n",{"type":41,"tag":479,"props":3395,"children":3396},{"class":481,"line":579},[3397],{"type":41,"tag":479,"props":3398,"children":3399},{"emptyLinePlaceholder":564},[3400],{"type":47,"value":567},{"type":41,"tag":479,"props":3402,"children":3403},{"class":481,"line":629},[3404],{"type":41,"tag":479,"props":3405,"children":3406},{},[3407],{"type":47,"value":3385},{"type":41,"tag":479,"props":3409,"children":3410},{"class":481,"line":637},[3411],{"type":41,"tag":479,"props":3412,"children":3413},{},[3414],{"type":47,"value":3415},"    private SlingRepository repository;\n",{"type":41,"tag":479,"props":3417,"children":3418},{"class":481,"line":646},[3419],{"type":41,"tag":479,"props":3420,"children":3421},{"emptyLinePlaceholder":564},[3422],{"type":47,"value":567},{"type":41,"tag":479,"props":3424,"children":3425},{"class":481,"line":692},[3426],{"type":41,"tag":479,"props":3427,"children":3428},{},[3429],{"type":47,"value":3430},"    @Reference(cardinality = ReferenceCardinality.OPTIONAL)\n",{"type":41,"tag":479,"props":3432,"children":3433},{"class":481,"line":700},[3434],{"type":41,"tag":479,"props":3435,"children":3436},{},[3437],{"type":47,"value":3438},"    private ConfigurationAdmin configAdmin;  \u002F\u002F Optional - keep as field\n",{"type":41,"tag":479,"props":3440,"children":3441},{"class":481,"line":709},[3442],{"type":41,"tag":479,"props":3443,"children":3444},{"emptyLinePlaceholder":564},[3445],{"type":47,"value":567},{"type":41,"tag":479,"props":3447,"children":3448},{"class":481,"line":1520},[3449],{"type":41,"tag":479,"props":3450,"children":3451},{},[3452],{"type":47,"value":3453},"    public void doSomething() {\n",{"type":41,"tag":479,"props":3455,"children":3456},{"class":481,"line":1528},[3457],{"type":41,"tag":479,"props":3458,"children":3459},{},[3460],{"type":47,"value":3461},"        \u002F\u002F Use resolverFactory and repository\n",{"type":41,"tag":479,"props":3463,"children":3464},{"class":481,"line":1536},[3465],{"type":41,"tag":479,"props":3466,"children":3467},{},[3468],{"type":47,"value":1478},{"type":41,"tag":479,"props":3470,"children":3471},{"class":481,"line":1545},[3472],{"type":41,"tag":479,"props":3473,"children":3474},{},[3475],{"type":47,"value":1486},{"type":41,"tag":479,"props":3477,"children":3478},{"class":481,"line":1554},[3479],{"type":41,"tag":479,"props":3480,"children":3481},{"emptyLinePlaceholder":564},[3482],{"type":47,"value":567},{"type":41,"tag":479,"props":3484,"children":3485},{"class":481,"line":1563},[3486],{"type":41,"tag":479,"props":3487,"children":3488},{},[3489],{"type":47,"value":3490},"\u002F\u002F After optimization (Step 7) - Constructor injection for mandatory references\n",{"type":41,"tag":479,"props":3492,"children":3493},{"class":481,"line":1572},[3494],{"type":41,"tag":479,"props":3495,"children":3496},{},[3497],{"type":47,"value":3363},{"type":41,"tag":479,"props":3499,"children":3500},{"class":481,"line":1580},[3501],{"type":41,"tag":479,"props":3502,"children":3503},{},[3504],{"type":47,"value":1446},{"type":41,"tag":479,"props":3506,"children":3507},{"class":481,"line":1588},[3508],{"type":41,"tag":479,"props":3509,"children":3510},{"emptyLinePlaceholder":564},[3511],{"type":47,"value":567},{"type":41,"tag":479,"props":3513,"children":3514},{"class":481,"line":1596},[3515],{"type":41,"tag":479,"props":3516,"children":3517},{},[3518],{"type":47,"value":3519},"    private final ResourceResolverFactory resolverFactory;\n",{"type":41,"tag":479,"props":3521,"children":3522},{"class":481,"line":1605},[3523],{"type":41,"tag":479,"props":3524,"children":3525},{},[3526],{"type":47,"value":3527},"    private final SlingRepository repository;\n",{"type":41,"tag":479,"props":3529,"children":3530},{"class":481,"line":1614},[3531],{"type":41,"tag":479,"props":3532,"children":3533},{"emptyLinePlaceholder":564},[3534],{"type":47,"value":567},{"type":41,"tag":479,"props":3536,"children":3537},{"class":481,"line":1623},[3538],{"type":41,"tag":479,"props":3539,"children":3540},{},[3541],{"type":47,"value":3542},"    \u002F\u002F Optional reference stays as field injection\n",{"type":41,"tag":479,"props":3544,"children":3545},{"class":481,"line":1631},[3546],{"type":41,"tag":479,"props":3547,"children":3548},{},[3549],{"type":47,"value":3430},{"type":41,"tag":479,"props":3551,"children":3552},{"class":481,"line":3079},[3553],{"type":41,"tag":479,"props":3554,"children":3555},{},[3556],{"type":47,"value":3557},"    private ConfigurationAdmin configAdmin;\n",{"type":41,"tag":479,"props":3559,"children":3560},{"class":481,"line":3087},[3561],{"type":41,"tag":479,"props":3562,"children":3563},{"emptyLinePlaceholder":564},[3564],{"type":47,"value":567},{"type":41,"tag":479,"props":3566,"children":3567},{"class":481,"line":3095},[3568],{"type":41,"tag":479,"props":3569,"children":3570},{},[3571],{"type":47,"value":1454},{"type":41,"tag":479,"props":3573,"children":3574},{"class":481,"line":3103},[3575],{"type":41,"tag":479,"props":3576,"children":3577},{},[3578],{"type":47,"value":3579},"    public MyService(\n",{"type":41,"tag":479,"props":3581,"children":3582},{"class":481,"line":26},[3583],{"type":41,"tag":479,"props":3584,"children":3585},{},[3586],{"type":47,"value":3587},"        @Reference ResourceResolverFactory resolverFactory,\n",{"type":41,"tag":479,"props":3589,"children":3590},{"class":481,"line":3118},[3591],{"type":41,"tag":479,"props":3592,"children":3593},{},[3594],{"type":47,"value":3595},"        @Reference SlingRepository repository\n",{"type":41,"tag":479,"props":3597,"children":3598},{"class":481,"line":3126},[3599],{"type":41,"tag":479,"props":3600,"children":3601},{},[3602],{"type":47,"value":3603},"    ) {\n",{"type":41,"tag":479,"props":3605,"children":3606},{"class":481,"line":3134},[3607],{"type":41,"tag":479,"props":3608,"children":3609},{},[3610],{"type":47,"value":3611},"        this.resolverFactory = resolverFactory;\n",{"type":41,"tag":479,"props":3613,"children":3614},{"class":481,"line":3142},[3615],{"type":41,"tag":479,"props":3616,"children":3617},{},[3618],{"type":47,"value":3619},"        this.repository = repository;\n",{"type":41,"tag":479,"props":3621,"children":3622},{"class":481,"line":3150},[3623],{"type":41,"tag":479,"props":3624,"children":3625},{},[3626],{"type":47,"value":1478},{"type":41,"tag":479,"props":3628,"children":3629},{"class":481,"line":3158},[3630],{"type":41,"tag":479,"props":3631,"children":3632},{"emptyLinePlaceholder":564},[3633],{"type":47,"value":567},{"type":41,"tag":479,"props":3635,"children":3636},{"class":481,"line":3166},[3637],{"type":41,"tag":479,"props":3638,"children":3639},{},[3640],{"type":47,"value":3453},{"type":41,"tag":479,"props":3642,"children":3643},{"class":481,"line":3175},[3644],{"type":41,"tag":479,"props":3645,"children":3646},{},[3647],{"type":47,"value":3648},"        \u002F\u002F Use resolverFactory and repository (guaranteed non-null)\n",{"type":41,"tag":479,"props":3650,"children":3651},{"class":481,"line":3184},[3652],{"type":41,"tag":479,"props":3653,"children":3654},{},[3655],{"type":47,"value":1478},{"type":41,"tag":479,"props":3657,"children":3658},{"class":481,"line":3192},[3659],{"type":41,"tag":479,"props":3660,"children":3661},{},[3662],{"type":47,"value":1486},{"type":41,"tag":50,"props":3664,"children":3665},{},[3666],{"type":41,"tag":99,"props":3667,"children":3668},{},[3669],{"type":47,"value":3670},"When to use constructor injection for references:",{"type":41,"tag":91,"props":3672,"children":3673},{},[3674,3687,3700],{"type":41,"tag":95,"props":3675,"children":3676},{},[3677,3679,3685],{"type":47,"value":3678},"✅ Mandatory references (",{"type":41,"tag":68,"props":3680,"children":3682},{"className":3681},[],[3683],{"type":47,"value":3684},"cardinality = MANDATORY",{"type":47,"value":3686}," or no cardinality specified)",{"type":41,"tag":95,"props":3688,"children":3689},{},[3690,3692,3698],{"type":47,"value":3691},"✅ Static references (",{"type":41,"tag":68,"props":3693,"children":3695},{"className":3694},[],[3696],{"type":47,"value":3697},"policy = STATIC",{"type":47,"value":3699}," or no policy specified)",{"type":41,"tag":95,"props":3701,"children":3702},{},[3703],{"type":47,"value":3704},"✅ Unary references (single service, not collections)",{"type":41,"tag":50,"props":3706,"children":3707},{},[3708],{"type":41,"tag":99,"props":3709,"children":3710},{},[3711],{"type":47,"value":3712},"When to keep field injection:",{"type":41,"tag":91,"props":3714,"children":3715},{},[3716,3728,3740,3759],{"type":41,"tag":95,"props":3717,"children":3718},{},[3719,3721,3727],{"type":47,"value":3720},"❌ Optional references (",{"type":41,"tag":68,"props":3722,"children":3724},{"className":3723},[],[3725],{"type":47,"value":3726},"cardinality = OPTIONAL",{"type":47,"value":1062},{"type":41,"tag":95,"props":3729,"children":3730},{},[3731,3733,3739],{"type":47,"value":3732},"❌ Dynamic references (",{"type":41,"tag":68,"props":3734,"children":3736},{"className":3735},[],[3737],{"type":47,"value":3738},"policy = DYNAMIC",{"type":47,"value":1062},{"type":41,"tag":95,"props":3741,"children":3742},{},[3743,3745,3751,3752,3758],{"type":47,"value":3744},"❌ Multiple references (",{"type":41,"tag":68,"props":3746,"children":3748},{"className":3747},[],[3749],{"type":47,"value":3750},"cardinality = MULTIPLE",{"type":47,"value":1277},{"type":41,"tag":68,"props":3753,"children":3755},{"className":3754},[],[3756],{"type":47,"value":3757},"AT_LEAST_ONE",{"type":47,"value":1062},{"type":41,"tag":95,"props":3760,"children":3761},{},[3762],{"type":47,"value":3763},"❌ References with custom bind\u002Funbind methods",{"type":41,"tag":785,"props":3765,"children":3767},{"id":3766},"_7c-combined-configuration-and-references",[3768],{"type":47,"value":3769},"7c. Combined Configuration and References",{"type":41,"tag":50,"props":3771,"children":3772},{},[3773],{"type":47,"value":3774},"You can combine configuration and reference injection in a single constructor:",{"type":41,"tag":468,"props":3776,"children":3778},{"className":1409,"code":3777,"language":14,"meta":473,"style":473},"\u002F\u002F Optimized: Constructor injection for config + mandatory static references\n@Component(service = MyService.class)\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\")\n        int timeout() default 30;\n    }\n\n    private final int timeout;\n    private final ResourceResolverFactory resolverFactory;\n    private final SlingRepository repository;\n\n    \u002F\u002F Optional\u002Fdynamic references stay as field injection\n    @Reference(cardinality = ReferenceCardinality.OPTIONAL)\n    private ConfigurationAdmin configAdmin;\n\n    @Activate\n    public MyService(\n        Config config,\n        @Reference ResourceResolverFactory resolverFactory,\n        @Reference SlingRepository repository\n    ) {\n        this.timeout = config.timeout();\n        this.resolverFactory = resolverFactory;\n        this.repository = repository;\n    }\n}\n",[3779],{"type":41,"tag":68,"props":3780,"children":3781},{"__ignoreMap":473},[3782,3790,3797,3804,3811,3818,3825,3832,3839,3846,3853,3860,3867,3874,3881,3888,3896,3903,3910,3917,3924,3931,3939,3946,3953,3960,3967,3974,3981,3988],{"type":41,"tag":479,"props":3783,"children":3784},{"class":481,"line":482},[3785],{"type":41,"tag":479,"props":3786,"children":3787},{},[3788],{"type":47,"value":3789},"\u002F\u002F Optimized: Constructor injection for config + mandatory static references\n",{"type":41,"tag":479,"props":3791,"children":3792},{"class":481,"line":492},[3793],{"type":41,"tag":479,"props":3794,"children":3795},{},[3796],{"type":47,"value":3363},{"type":41,"tag":479,"props":3798,"children":3799},{"class":481,"line":508},[3800],{"type":41,"tag":479,"props":3801,"children":3802},{},[3803],{"type":47,"value":1517},{"type":41,"tag":479,"props":3805,"children":3806},{"class":481,"line":526},[3807],{"type":41,"tag":479,"props":3808,"children":3809},{},[3810],{"type":47,"value":1446},{"type":41,"tag":479,"props":3812,"children":3813},{"class":481,"line":560},[3814],{"type":41,"tag":479,"props":3815,"children":3816},{"emptyLinePlaceholder":564},[3817],{"type":47,"value":567},{"type":41,"tag":479,"props":3819,"children":3820},{"class":481,"line":570},[3821],{"type":41,"tag":479,"props":3822,"children":3823},{},[3824],{"type":47,"value":2921},{"type":41,"tag":479,"props":3826,"children":3827},{"class":481,"line":579},[3828],{"type":41,"tag":479,"props":3829,"children":3830},{},[3831],{"type":47,"value":1551},{"type":41,"tag":479,"props":3833,"children":3834},{"class":481,"line":629},[3835],{"type":41,"tag":479,"props":3836,"children":3837},{},[3838],{"type":47,"value":2936},{"type":41,"tag":479,"props":3840,"children":3841},{"class":481,"line":637},[3842],{"type":41,"tag":479,"props":3843,"children":3844},{},[3845],{"type":47,"value":1569},{"type":41,"tag":479,"props":3847,"children":3848},{"class":481,"line":646},[3849],{"type":41,"tag":479,"props":3850,"children":3851},{},[3852],{"type":47,"value":1478},{"type":41,"tag":479,"props":3854,"children":3855},{"class":481,"line":692},[3856],{"type":41,"tag":479,"props":3857,"children":3858},{"emptyLinePlaceholder":564},[3859],{"type":47,"value":567},{"type":41,"tag":479,"props":3861,"children":3862},{"class":481,"line":700},[3863],{"type":41,"tag":479,"props":3864,"children":3865},{},[3866],{"type":47,"value":3172},{"type":41,"tag":479,"props":3868,"children":3869},{"class":481,"line":709},[3870],{"type":41,"tag":479,"props":3871,"children":3872},{},[3873],{"type":47,"value":3519},{"type":41,"tag":479,"props":3875,"children":3876},{"class":481,"line":1520},[3877],{"type":41,"tag":479,"props":3878,"children":3879},{},[3880],{"type":47,"value":3527},{"type":41,"tag":479,"props":3882,"children":3883},{"class":481,"line":1528},[3884],{"type":41,"tag":479,"props":3885,"children":3886},{"emptyLinePlaceholder":564},[3887],{"type":47,"value":567},{"type":41,"tag":479,"props":3889,"children":3890},{"class":481,"line":1536},[3891],{"type":41,"tag":479,"props":3892,"children":3893},{},[3894],{"type":47,"value":3895},"    \u002F\u002F Optional\u002Fdynamic references stay as field injection\n",{"type":41,"tag":479,"props":3897,"children":3898},{"class":481,"line":1545},[3899],{"type":41,"tag":479,"props":3900,"children":3901},{},[3902],{"type":47,"value":3430},{"type":41,"tag":479,"props":3904,"children":3905},{"class":481,"line":1554},[3906],{"type":41,"tag":479,"props":3907,"children":3908},{},[3909],{"type":47,"value":3557},{"type":41,"tag":479,"props":3911,"children":3912},{"class":481,"line":1563},[3913],{"type":41,"tag":479,"props":3914,"children":3915},{"emptyLinePlaceholder":564},[3916],{"type":47,"value":567},{"type":41,"tag":479,"props":3918,"children":3919},{"class":481,"line":1572},[3920],{"type":41,"tag":479,"props":3921,"children":3922},{},[3923],{"type":47,"value":1454},{"type":41,"tag":479,"props":3925,"children":3926},{"class":481,"line":1580},[3927],{"type":41,"tag":479,"props":3928,"children":3929},{},[3930],{"type":47,"value":3579},{"type":41,"tag":479,"props":3932,"children":3933},{"class":481,"line":1588},[3934],{"type":41,"tag":479,"props":3935,"children":3936},{},[3937],{"type":47,"value":3938},"        Config config,\n",{"type":41,"tag":479,"props":3940,"children":3941},{"class":481,"line":1596},[3942],{"type":41,"tag":479,"props":3943,"children":3944},{},[3945],{"type":47,"value":3587},{"type":41,"tag":479,"props":3947,"children":3948},{"class":481,"line":1605},[3949],{"type":41,"tag":479,"props":3950,"children":3951},{},[3952],{"type":47,"value":3595},{"type":41,"tag":479,"props":3954,"children":3955},{"class":481,"line":1614},[3956],{"type":41,"tag":479,"props":3957,"children":3958},{},[3959],{"type":47,"value":3603},{"type":41,"tag":479,"props":3961,"children":3962},{"class":481,"line":1623},[3963],{"type":41,"tag":479,"props":3964,"children":3965},{},[3966],{"type":47,"value":3025},{"type":41,"tag":479,"props":3968,"children":3969},{"class":481,"line":1631},[3970],{"type":41,"tag":479,"props":3971,"children":3972},{},[3973],{"type":47,"value":3611},{"type":41,"tag":479,"props":3975,"children":3976},{"class":481,"line":3079},[3977],{"type":41,"tag":479,"props":3978,"children":3979},{},[3980],{"type":47,"value":3619},{"type":41,"tag":479,"props":3982,"children":3983},{"class":481,"line":3087},[3984],{"type":41,"tag":479,"props":3985,"children":3986},{},[3987],{"type":47,"value":1478},{"type":41,"tag":479,"props":3989,"children":3990},{"class":481,"line":3095},[3991],{"type":41,"tag":479,"props":3992,"children":3993},{},[3994],{"type":47,"value":1486},{"type":41,"tag":50,"props":3996,"children":3997},{},[3998],{"type":41,"tag":99,"props":3999,"children":4000},{},[4001],{"type":47,"value":4002},"Important notes:",{"type":41,"tag":91,"props":4004,"children":4005},{},[4006,4018,4023,4035,4047],{"type":41,"tag":95,"props":4007,"children":4008},{},[4009,4011,4016],{"type":47,"value":4010},"Configuration parameter (if present) must be ",{"type":41,"tag":99,"props":4012,"children":4013},{},[4014],{"type":47,"value":4015},"first",{"type":47,"value":4017}," in constructor",{"type":41,"tag":95,"props":4019,"children":4020},{},[4021],{"type":47,"value":4022},"Reference parameters follow after configuration",{"type":41,"tag":95,"props":4024,"children":4025},{},[4026,4028,4033],{"type":47,"value":4027},"Constructor must be ",{"type":41,"tag":68,"props":4029,"children":4031},{"className":4030},[],[4032],{"type":47,"value":3260},{"type":47,"value":4034}," for OSGi to inject dependencies",{"type":41,"tag":95,"props":4036,"children":4037},{},[4038,4040,4045],{"type":47,"value":4039},"Use ",{"type":41,"tag":68,"props":4041,"children":4043},{"className":4042},[],[4044],{"type":47,"value":285},{"type":47,"value":4046}," annotation on each reference parameter",{"type":41,"tag":95,"props":4048,"children":4049},{},[4050],{"type":47,"value":4051},"Reference attributes (target, cardinality, etc.) can be specified on parameters",{"type":41,"tag":785,"props":4053,"children":4055},{"id":4054},"_7d-what-the-script-does-automatically",[4056],{"type":47,"value":4057},"7d. What the Script Does Automatically",{"type":41,"tag":50,"props":4059,"children":4060},{},[4061],{"type":47,"value":4062},"The script automatically:",{"type":41,"tag":91,"props":4064,"children":4065},{},[4066,4078,4089,4101,4106,4111,4123,4128],{"type":41,"tag":95,"props":4067,"children":4068},{},[4069,4071,4076],{"type":47,"value":4070},"✅ Identifies components with ",{"type":41,"tag":68,"props":4072,"children":4074},{"className":4073},[],[4075],{"type":47,"value":272},{"type":47,"value":4077}," methods",{"type":41,"tag":95,"props":4079,"children":4080},{},[4081,4083,4088],{"type":47,"value":4082},"✅ Identifies mandatory static unary ",{"type":41,"tag":68,"props":4084,"children":4086},{"className":4085},[],[4087],{"type":47,"value":285},{"type":47,"value":2808},{"type":41,"tag":95,"props":4090,"children":4091},{},[4092,4094,4099],{"type":47,"value":4093},"✅ Creates public constructor with ",{"type":41,"tag":68,"props":4095,"children":4097},{"className":4096},[],[4098],{"type":47,"value":1046},{"type":47,"value":4100}," annotation",{"type":41,"tag":95,"props":4102,"children":4103},{},[4104],{"type":47,"value":4105},"✅ Moves config parameter to constructor (first parameter)",{"type":41,"tag":95,"props":4107,"children":4108},{},[4109],{"type":47,"value":4110},"✅ Moves eligible references to constructor parameters",{"type":41,"tag":95,"props":4112,"children":4113},{},[4114,4116,4121],{"type":47,"value":4115},"✅ Makes fields ",{"type":41,"tag":68,"props":4117,"children":4119},{"className":4118},[],[4120],{"type":47,"value":298},{"type":47,"value":4122}," for immutability",{"type":41,"tag":95,"props":4124,"children":4125},{},[4126],{"type":47,"value":4127},"✅ Preserves optional\u002Fdynamic\u002Fmultiple references as field injection",{"type":41,"tag":95,"props":4129,"children":4130},{},[4131],{"type":47,"value":4132},"✅ Generates comprehensive migration statistics",{"type":41,"tag":50,"props":4134,"children":4135},{},[4136,4141],{"type":41,"tag":99,"props":4137,"children":4138},{},[4139],{"type":47,"value":4140},"What the script does NOT migrate",{"type":47,"value":4142}," (kept as field injection):",{"type":41,"tag":91,"props":4144,"children":4145},{},[4146,4156,4166,4182,4186],{"type":41,"tag":95,"props":4147,"children":4148},{},[4149,4150,4155],{"type":47,"value":3720},{"type":41,"tag":68,"props":4151,"children":4153},{"className":4152},[],[4154],{"type":47,"value":3726},{"type":47,"value":1062},{"type":41,"tag":95,"props":4157,"children":4158},{},[4159,4160,4165],{"type":47,"value":3732},{"type":41,"tag":68,"props":4161,"children":4163},{"className":4162},[],[4164],{"type":47,"value":3738},{"type":47,"value":1062},{"type":41,"tag":95,"props":4167,"children":4168},{},[4169,4170,4175,4176,4181],{"type":47,"value":3744},{"type":41,"tag":68,"props":4171,"children":4173},{"className":4172},[],[4174],{"type":47,"value":3750},{"type":47,"value":1277},{"type":41,"tag":68,"props":4177,"children":4179},{"className":4178},[],[4180],{"type":47,"value":3757},{"type":47,"value":1062},{"type":41,"tag":95,"props":4183,"children":4184},{},[4185],{"type":47,"value":3763},{"type":41,"tag":95,"props":4187,"children":4188},{},[4189],{"type":47,"value":4190},"❌ Collection references (List, Set, Collection)",{"type":41,"tag":785,"props":4192,"children":4194},{"id":4193},"_7e-post-migration-verification",[4195],{"type":47,"value":4196},"7e. Post-Migration Verification",{"type":41,"tag":50,"props":4198,"children":4199},{},[4200],{"type":47,"value":4201},"After running the automated migration, verify the changes:",{"type":41,"tag":1715,"props":4203,"children":4204},{},[4205,4223,4265,4292],{"type":41,"tag":95,"props":4206,"children":4207},{},[4208,4213,4214],{"type":41,"tag":99,"props":4209,"children":4210},{},[4211],{"type":47,"value":4212},"Review the migration statistics",{"type":47,"value":2127},{"type":41,"tag":468,"props":4215,"children":4218},{"className":4216,"code":4217,"language":47},[1321],"======================================================================\nCONSTRUCTOR INJECTION MIGRATION SUMMARY\n======================================================================\nFiles processed:              15\nFiles changed:                8\nComponents migrated:          8\nConfigs converted:            6\nReferences converted:         14\nFields made final:            20\n======================================================================\n",[4219],{"type":41,"tag":68,"props":4220,"children":4221},{"__ignoreMap":473},[4222],{"type":47,"value":4217},{"type":41,"tag":95,"props":4224,"children":4225},{},[4226,4231,4232],{"type":41,"tag":99,"props":4227,"children":4228},{},[4229],{"type":47,"value":4230},"Test thoroughly",{"type":47,"value":2127},{"type":41,"tag":468,"props":4233,"children":4235},{"className":470,"code":4234,"language":472,"meta":473,"style":473},"mvn clean install\nmvn test\n",[4236],{"type":41,"tag":68,"props":4237,"children":4238},{"__ignoreMap":473},[4239,4254],{"type":41,"tag":479,"props":4240,"children":4241},{"class":481,"line":482},[4242,4246,4250],{"type":41,"tag":479,"props":4243,"children":4244},{"style":496},[4245],{"type":47,"value":2374},{"type":41,"tag":479,"props":4247,"children":4248},{"style":502},[4249],{"type":47,"value":2379},{"type":41,"tag":479,"props":4251,"children":4252},{"style":502},[4253],{"type":47,"value":2384},{"type":41,"tag":479,"props":4255,"children":4256},{"class":481,"line":492},[4257,4261],{"type":41,"tag":479,"props":4258,"children":4259},{"style":496},[4260],{"type":47,"value":2374},{"type":41,"tag":479,"props":4262,"children":4263},{"style":502},[4264],{"type":47,"value":2411},{"type":41,"tag":95,"props":4266,"children":4267},{},[4268,4273,4274],{"type":41,"tag":99,"props":4269,"children":4270},{},[4271],{"type":47,"value":4272},"Verify OSGi activation",{"type":47,"value":2127},{"type":41,"tag":91,"props":4275,"children":4276},{},[4277,4282,4287],{"type":41,"tag":95,"props":4278,"children":4279},{},[4280],{"type":47,"value":4281},"Check OSGi console for component activation",{"type":41,"tag":95,"props":4283,"children":4284},{},[4285],{"type":47,"value":4286},"Verify all references are satisfied",{"type":41,"tag":95,"props":4288,"children":4289},{},[4290],{"type":47,"value":4291},"Test component functionality",{"type":41,"tag":95,"props":4293,"children":4294},{},[4295,4300,4301],{"type":41,"tag":99,"props":4296,"children":4297},{},[4298],{"type":47,"value":4299},"Review generated constructors",{"type":47,"value":2127},{"type":41,"tag":91,"props":4302,"children":4303},{},[4304,4316,4326,4331,4336,4341],{"type":41,"tag":95,"props":4305,"children":4306},{},[4307,4309,4314],{"type":47,"value":4308},"Constructor is ",{"type":41,"tag":68,"props":4310,"children":4312},{"className":4311},[],[4313],{"type":47,"value":3260},{"type":47,"value":4315}," ✓",{"type":41,"tag":95,"props":4317,"children":4318},{},[4319,4324],{"type":41,"tag":68,"props":4320,"children":4322},{"className":4321},[],[4323],{"type":47,"value":1046},{"type":47,"value":4325}," annotation on constructor ✓",{"type":41,"tag":95,"props":4327,"children":4328},{},[4329],{"type":47,"value":4330},"Config parameter is first (if present) ✓",{"type":41,"tag":95,"props":4332,"children":4333},{},[4334],{"type":47,"value":4335},"Only mandatory static unary references moved to constructor ✓",{"type":41,"tag":95,"props":4337,"children":4338},{},[4339],{"type":47,"value":4340},"Optional\u002Fdynamic references remain as fields ✓",{"type":41,"tag":95,"props":4342,"children":4343},{},[4344,4346,4351],{"type":47,"value":4345},"Fields are ",{"type":41,"tag":68,"props":4347,"children":4349},{"className":4348},[],[4350],{"type":47,"value":298},{"type":47,"value":4352}," where appropriate ✓",{"type":41,"tag":50,"props":4354,"children":4355},{},[4356,4361,4363,4369,4371,4377],{"type":41,"tag":99,"props":4357,"children":4358},{},[4359],{"type":47,"value":4360},"If tests fail",{"type":47,"value":4362},": Use ",{"type":41,"tag":68,"props":4364,"children":4366},{"className":4365},[],[4367],{"type":47,"value":4368},"git diff",{"type":47,"value":4370}," to review changes and ",{"type":41,"tag":68,"props":4372,"children":4374},{"className":4373},[],[4375],{"type":47,"value":4376},"git checkout .",{"type":47,"value":4378}," to revert if needed.",{"type":41,"tag":56,"props":4380,"children":4382},{"id":4381},"advanced-usage",[4383],{"type":47,"value":4384},"Advanced Usage",{"type":41,"tag":451,"props":4386,"children":4388},{"id":4387},"command-line-options",[4389],{"type":47,"value":4390},"Command-Line Options",{"type":41,"tag":785,"props":4392,"children":4394},{"id":4393},"constructor-injection-migration-script-step-7",[4395],{"type":47,"value":4396},"Constructor Injection Migration Script (Step 7)",{"type":41,"tag":468,"props":4398,"children":4400},{"className":470,"code":4399,"language":472,"meta":473,"style":473},"python3 scripts\u002Fmigrate_constructor_injection.py [OPTIONS] PATH\n\nOptions:\n  --dry-run          Preview changes without modifying files\n  --validate         Validate migrated code for common issues\n\nExamples:\n  # Preview all changes\n  python3 scripts\u002Fmigrate_constructor_injection.py src\u002F --dry-run\n\n  # Migrate with validation\n  python3 scripts\u002Fmigrate_constructor_injection.py src\u002F --validate\n\n  # Single file migration\n  python3 scripts\u002Fmigrate_constructor_injection.py src\u002Fmain\u002Fjava\u002FMyService.java\n\n  # Use git to review changes\n  git diff src\u002F\n",[4401],{"type":41,"tag":68,"props":4402,"children":4403},{"__ignoreMap":473},[4404,4421,4428,4436,4469,4507,4514,4522,4530,4551,4558,4566,4585,4592,4600,4616,4623,4631],{"type":41,"tag":479,"props":4405,"children":4406},{"class":481,"line":482},[4407,4411,4415],{"type":41,"tag":479,"props":4408,"children":4409},{"style":496},[4410],{"type":47,"value":813},{"type":41,"tag":479,"props":4412,"children":4413},{"style":502},[4414],{"type":47,"value":2649},{"type":41,"tag":479,"props":4416,"children":4418},{"style":4417},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[4419],{"type":47,"value":4420}," [OPTIONS] PATH\n",{"type":41,"tag":479,"props":4422,"children":4423},{"class":481,"line":492},[4424],{"type":41,"tag":479,"props":4425,"children":4426},{"emptyLinePlaceholder":564},[4427],{"type":47,"value":567},{"type":41,"tag":479,"props":4429,"children":4430},{"class":481,"line":508},[4431],{"type":41,"tag":479,"props":4432,"children":4433},{"style":496},[4434],{"type":47,"value":4435},"Options:\n",{"type":41,"tag":479,"props":4437,"children":4438},{"class":481,"line":526},[4439,4444,4449,4454,4459,4464],{"type":41,"tag":479,"props":4440,"children":4441},{"style":496},[4442],{"type":47,"value":4443},"  --dry-run",{"type":41,"tag":479,"props":4445,"children":4446},{"style":502},[4447],{"type":47,"value":4448},"          Preview",{"type":41,"tag":479,"props":4450,"children":4451},{"style":502},[4452],{"type":47,"value":4453}," changes",{"type":41,"tag":479,"props":4455,"children":4456},{"style":502},[4457],{"type":47,"value":4458}," without",{"type":41,"tag":479,"props":4460,"children":4461},{"style":502},[4462],{"type":47,"value":4463}," modifying",{"type":41,"tag":479,"props":4465,"children":4466},{"style":502},[4467],{"type":47,"value":4468}," files\n",{"type":41,"tag":479,"props":4470,"children":4471},{"class":481,"line":560},[4472,4477,4482,4487,4492,4497,4502],{"type":41,"tag":479,"props":4473,"children":4474},{"style":496},[4475],{"type":47,"value":4476},"  --validate",{"type":41,"tag":479,"props":4478,"children":4479},{"style":502},[4480],{"type":47,"value":4481},"         Validate",{"type":41,"tag":479,"props":4483,"children":4484},{"style":502},[4485],{"type":47,"value":4486}," migrated",{"type":41,"tag":479,"props":4488,"children":4489},{"style":502},[4490],{"type":47,"value":4491}," code",{"type":41,"tag":479,"props":4493,"children":4494},{"style":502},[4495],{"type":47,"value":4496}," for",{"type":41,"tag":479,"props":4498,"children":4499},{"style":502},[4500],{"type":47,"value":4501}," common",{"type":41,"tag":479,"props":4503,"children":4504},{"style":502},[4505],{"type":47,"value":4506}," issues\n",{"type":41,"tag":479,"props":4508,"children":4509},{"class":481,"line":570},[4510],{"type":41,"tag":479,"props":4511,"children":4512},{"emptyLinePlaceholder":564},[4513],{"type":47,"value":567},{"type":41,"tag":479,"props":4515,"children":4516},{"class":481,"line":579},[4517],{"type":41,"tag":479,"props":4518,"children":4519},{"style":496},[4520],{"type":47,"value":4521},"Examples:\n",{"type":41,"tag":479,"props":4523,"children":4524},{"class":481,"line":629},[4525],{"type":41,"tag":479,"props":4526,"children":4527},{"style":486},[4528],{"type":47,"value":4529},"  # Preview all changes\n",{"type":41,"tag":479,"props":4531,"children":4532},{"class":481,"line":637},[4533,4538,4542,4547],{"type":41,"tag":479,"props":4534,"children":4535},{"style":496},[4536],{"type":47,"value":4537},"  python3",{"type":41,"tag":479,"props":4539,"children":4540},{"style":502},[4541],{"type":47,"value":2649},{"type":41,"tag":479,"props":4543,"children":4544},{"style":502},[4545],{"type":47,"value":4546}," src\u002F",{"type":41,"tag":479,"props":4548,"children":4549},{"style":502},[4550],{"type":47,"value":828},{"type":41,"tag":479,"props":4552,"children":4553},{"class":481,"line":646},[4554],{"type":41,"tag":479,"props":4555,"children":4556},{"emptyLinePlaceholder":564},[4557],{"type":47,"value":567},{"type":41,"tag":479,"props":4559,"children":4560},{"class":481,"line":692},[4561],{"type":41,"tag":479,"props":4562,"children":4563},{"style":486},[4564],{"type":47,"value":4565},"  # Migrate with validation\n",{"type":41,"tag":479,"props":4567,"children":4568},{"class":481,"line":700},[4569,4573,4577,4581],{"type":41,"tag":479,"props":4570,"children":4571},{"style":496},[4572],{"type":47,"value":4537},{"type":41,"tag":479,"props":4574,"children":4575},{"style":502},[4576],{"type":47,"value":2649},{"type":41,"tag":479,"props":4578,"children":4579},{"style":502},[4580],{"type":47,"value":4546},{"type":41,"tag":479,"props":4582,"children":4583},{"style":502},[4584],{"type":47,"value":863},{"type":41,"tag":479,"props":4586,"children":4587},{"class":481,"line":709},[4588],{"type":41,"tag":479,"props":4589,"children":4590},{"emptyLinePlaceholder":564},[4591],{"type":47,"value":567},{"type":41,"tag":479,"props":4593,"children":4594},{"class":481,"line":1520},[4595],{"type":41,"tag":479,"props":4596,"children":4597},{"style":486},[4598],{"type":47,"value":4599},"  # Single file migration\n",{"type":41,"tag":479,"props":4601,"children":4602},{"class":481,"line":1528},[4603,4607,4611],{"type":41,"tag":479,"props":4604,"children":4605},{"style":496},[4606],{"type":47,"value":4537},{"type":41,"tag":479,"props":4608,"children":4609},{"style":502},[4610],{"type":47,"value":2649},{"type":41,"tag":479,"props":4612,"children":4613},{"style":502},[4614],{"type":47,"value":4615}," src\u002Fmain\u002Fjava\u002FMyService.java\n",{"type":41,"tag":479,"props":4617,"children":4618},{"class":481,"line":1536},[4619],{"type":41,"tag":479,"props":4620,"children":4621},{"emptyLinePlaceholder":564},[4622],{"type":47,"value":567},{"type":41,"tag":479,"props":4624,"children":4625},{"class":481,"line":1545},[4626],{"type":41,"tag":479,"props":4627,"children":4628},{"style":486},[4629],{"type":47,"value":4630},"  # Use git to review changes\n",{"type":41,"tag":479,"props":4632,"children":4633},{"class":481,"line":1554},[4634,4639,4644],{"type":41,"tag":479,"props":4635,"children":4636},{"style":496},[4637],{"type":47,"value":4638},"  git",{"type":41,"tag":479,"props":4640,"children":4641},{"style":502},[4642],{"type":47,"value":4643}," diff",{"type":41,"tag":479,"props":4645,"children":4646},{"style":502},[4647],{"type":47,"value":4648}," src\u002F\n",{"type":41,"tag":785,"props":4650,"children":4652},{"id":4651},"java-migration-script-step-2",[4653],{"type":47,"value":4654},"Java Migration Script (Step 2)",{"type":41,"tag":468,"props":4656,"children":4658},{"className":470,"code":4657,"language":472,"meta":473,"style":473},"python3 scripts\u002Fmigrate_annotations.py [OPTIONS] PATH\n\nOptions:\n  --dry-run          Preview changes without modifying files\n  --validate         Validate migrated code for common issues\n\nExamples:\n  # Preview all changes\n  python3 scripts\u002Fmigrate_annotations.py src\u002F --dry-run\n\n  # Migrate with validation\n  python3 scripts\u002Fmigrate_annotations.py src\u002F --validate\n\n  # Use git to review changes\n  git diff src\u002F\n",[4659],{"type":41,"tag":68,"props":4660,"children":4661},{"__ignoreMap":473},[4662,4677,4684,4691,4718,4749,4756,4763,4770,4789,4796,4803,4822,4829,4836],{"type":41,"tag":479,"props":4663,"children":4664},{"class":481,"line":482},[4665,4669,4673],{"type":41,"tag":479,"props":4666,"children":4667},{"style":496},[4668],{"type":47,"value":813},{"type":41,"tag":479,"props":4670,"children":4671},{"style":502},[4672],{"type":47,"value":818},{"type":41,"tag":479,"props":4674,"children":4675},{"style":4417},[4676],{"type":47,"value":4420},{"type":41,"tag":479,"props":4678,"children":4679},{"class":481,"line":492},[4680],{"type":41,"tag":479,"props":4681,"children":4682},{"emptyLinePlaceholder":564},[4683],{"type":47,"value":567},{"type":41,"tag":479,"props":4685,"children":4686},{"class":481,"line":508},[4687],{"type":41,"tag":479,"props":4688,"children":4689},{"style":496},[4690],{"type":47,"value":4435},{"type":41,"tag":479,"props":4692,"children":4693},{"class":481,"line":526},[4694,4698,4702,4706,4710,4714],{"type":41,"tag":479,"props":4695,"children":4696},{"style":496},[4697],{"type":47,"value":4443},{"type":41,"tag":479,"props":4699,"children":4700},{"style":502},[4701],{"type":47,"value":4448},{"type":41,"tag":479,"props":4703,"children":4704},{"style":502},[4705],{"type":47,"value":4453},{"type":41,"tag":479,"props":4707,"children":4708},{"style":502},[4709],{"type":47,"value":4458},{"type":41,"tag":479,"props":4711,"children":4712},{"style":502},[4713],{"type":47,"value":4463},{"type":41,"tag":479,"props":4715,"children":4716},{"style":502},[4717],{"type":47,"value":4468},{"type":41,"tag":479,"props":4719,"children":4720},{"class":481,"line":560},[4721,4725,4729,4733,4737,4741,4745],{"type":41,"tag":479,"props":4722,"children":4723},{"style":496},[4724],{"type":47,"value":4476},{"type":41,"tag":479,"props":4726,"children":4727},{"style":502},[4728],{"type":47,"value":4481},{"type":41,"tag":479,"props":4730,"children":4731},{"style":502},[4732],{"type":47,"value":4486},{"type":41,"tag":479,"props":4734,"children":4735},{"style":502},[4736],{"type":47,"value":4491},{"type":41,"tag":479,"props":4738,"children":4739},{"style":502},[4740],{"type":47,"value":4496},{"type":41,"tag":479,"props":4742,"children":4743},{"style":502},[4744],{"type":47,"value":4501},{"type":41,"tag":479,"props":4746,"children":4747},{"style":502},[4748],{"type":47,"value":4506},{"type":41,"tag":479,"props":4750,"children":4751},{"class":481,"line":570},[4752],{"type":41,"tag":479,"props":4753,"children":4754},{"emptyLinePlaceholder":564},[4755],{"type":47,"value":567},{"type":41,"tag":479,"props":4757,"children":4758},{"class":481,"line":579},[4759],{"type":41,"tag":479,"props":4760,"children":4761},{"style":496},[4762],{"type":47,"value":4521},{"type":41,"tag":479,"props":4764,"children":4765},{"class":481,"line":629},[4766],{"type":41,"tag":479,"props":4767,"children":4768},{"style":486},[4769],{"type":47,"value":4529},{"type":41,"tag":479,"props":4771,"children":4772},{"class":481,"line":637},[4773,4777,4781,4785],{"type":41,"tag":479,"props":4774,"children":4775},{"style":496},[4776],{"type":47,"value":4537},{"type":41,"tag":479,"props":4778,"children":4779},{"style":502},[4780],{"type":47,"value":818},{"type":41,"tag":479,"props":4782,"children":4783},{"style":502},[4784],{"type":47,"value":4546},{"type":41,"tag":479,"props":4786,"children":4787},{"style":502},[4788],{"type":47,"value":828},{"type":41,"tag":479,"props":4790,"children":4791},{"class":481,"line":646},[4792],{"type":41,"tag":479,"props":4793,"children":4794},{"emptyLinePlaceholder":564},[4795],{"type":47,"value":567},{"type":41,"tag":479,"props":4797,"children":4798},{"class":481,"line":692},[4799],{"type":41,"tag":479,"props":4800,"children":4801},{"style":486},[4802],{"type":47,"value":4565},{"type":41,"tag":479,"props":4804,"children":4805},{"class":481,"line":700},[4806,4810,4814,4818],{"type":41,"tag":479,"props":4807,"children":4808},{"style":496},[4809],{"type":47,"value":4537},{"type":41,"tag":479,"props":4811,"children":4812},{"style":502},[4813],{"type":47,"value":818},{"type":41,"tag":479,"props":4815,"children":4816},{"style":502},[4817],{"type":47,"value":4546},{"type":41,"tag":479,"props":4819,"children":4820},{"style":502},[4821],{"type":47,"value":863},{"type":41,"tag":479,"props":4823,"children":4824},{"class":481,"line":709},[4825],{"type":41,"tag":479,"props":4826,"children":4827},{"emptyLinePlaceholder":564},[4828],{"type":47,"value":567},{"type":41,"tag":479,"props":4830,"children":4831},{"class":481,"line":1520},[4832],{"type":41,"tag":479,"props":4833,"children":4834},{"style":486},[4835],{"type":47,"value":4630},{"type":41,"tag":479,"props":4837,"children":4838},{"class":481,"line":1528},[4839,4843,4847],{"type":41,"tag":479,"props":4840,"children":4841},{"style":496},[4842],{"type":47,"value":4638},{"type":41,"tag":479,"props":4844,"children":4845},{"style":502},[4846],{"type":47,"value":4643},{"type":41,"tag":479,"props":4848,"children":4849},{"style":502},[4850],{"type":47,"value":4648},{"type":41,"tag":785,"props":4852,"children":4854},{"id":4853},"pom-migration-script",[4855],{"type":47,"value":4856},"POM Migration Script",{"type":41,"tag":468,"props":4858,"children":4860},{"className":470,"code":4859,"language":472,"meta":473,"style":473},"python3 scripts\u002Fmigrate_pom.py [OPTIONS] PATH\n\nOptions:\n  --dry-run              Preview changes without modifying files\n  --validate             Validate migrated POMs\n  --add-metatype         Add metatype dependency\n  --auto-detect-metatype Auto-detect metatype usage from Java files\n  --detect-versions      Detect OSGi versions from existing deps (default: True)\n\nExamples:\n  # Migrate with automatic metatype detection\n  python3 scripts\u002Fmigrate_pom.py . --auto-detect-metatype\n\n  # Dry run with validation\n  python3 scripts\u002Fmigrate_pom.py . --dry-run --validate\n\n  # Use git to review changes\n  git diff pom.xml\n",[4861],{"type":41,"tag":68,"props":4862,"children":4863},{"__ignoreMap":473},[4864,4879,4886,4893,4921,4942,4965,5001,5052,5059,5066,5074,5093,5100,5108,5132,5139,5146],{"type":41,"tag":479,"props":4865,"children":4866},{"class":481,"line":482},[4867,4871,4875],{"type":41,"tag":479,"props":4868,"children":4869},{"style":496},[4870],{"type":47,"value":813},{"type":41,"tag":479,"props":4872,"children":4873},{"style":502},[4874],{"type":47,"value":1099},{"type":41,"tag":479,"props":4876,"children":4877},{"style":4417},[4878],{"type":47,"value":4420},{"type":41,"tag":479,"props":4880,"children":4881},{"class":481,"line":492},[4882],{"type":41,"tag":479,"props":4883,"children":4884},{"emptyLinePlaceholder":564},[4885],{"type":47,"value":567},{"type":41,"tag":479,"props":4887,"children":4888},{"class":481,"line":508},[4889],{"type":41,"tag":479,"props":4890,"children":4891},{"style":496},[4892],{"type":47,"value":4435},{"type":41,"tag":479,"props":4894,"children":4895},{"class":481,"line":526},[4896,4900,4905,4909,4913,4917],{"type":41,"tag":479,"props":4897,"children":4898},{"style":496},[4899],{"type":47,"value":4443},{"type":41,"tag":479,"props":4901,"children":4902},{"style":502},[4903],{"type":47,"value":4904},"              Preview",{"type":41,"tag":479,"props":4906,"children":4907},{"style":502},[4908],{"type":47,"value":4453},{"type":41,"tag":479,"props":4910,"children":4911},{"style":502},[4912],{"type":47,"value":4458},{"type":41,"tag":479,"props":4914,"children":4915},{"style":502},[4916],{"type":47,"value":4463},{"type":41,"tag":479,"props":4918,"children":4919},{"style":502},[4920],{"type":47,"value":4468},{"type":41,"tag":479,"props":4922,"children":4923},{"class":481,"line":560},[4924,4928,4933,4937],{"type":41,"tag":479,"props":4925,"children":4926},{"style":496},[4927],{"type":47,"value":4476},{"type":41,"tag":479,"props":4929,"children":4930},{"style":502},[4931],{"type":47,"value":4932},"             Validate",{"type":41,"tag":479,"props":4934,"children":4935},{"style":502},[4936],{"type":47,"value":4486},{"type":41,"tag":479,"props":4938,"children":4939},{"style":502},[4940],{"type":47,"value":4941}," POMs\n",{"type":41,"tag":479,"props":4943,"children":4944},{"class":481,"line":570},[4945,4950,4955,4960],{"type":41,"tag":479,"props":4946,"children":4947},{"style":496},[4948],{"type":47,"value":4949},"  --add-metatype",{"type":41,"tag":479,"props":4951,"children":4952},{"style":502},[4953],{"type":47,"value":4954},"         Add",{"type":41,"tag":479,"props":4956,"children":4957},{"style":502},[4958],{"type":47,"value":4959}," metatype",{"type":41,"tag":479,"props":4961,"children":4962},{"style":502},[4963],{"type":47,"value":4964}," dependency\n",{"type":41,"tag":479,"props":4966,"children":4967},{"class":481,"line":579},[4968,4973,4978,4982,4987,4992,4997],{"type":41,"tag":479,"props":4969,"children":4970},{"style":496},[4971],{"type":47,"value":4972},"  --auto-detect-metatype",{"type":41,"tag":479,"props":4974,"children":4975},{"style":502},[4976],{"type":47,"value":4977}," Auto-detect",{"type":41,"tag":479,"props":4979,"children":4980},{"style":502},[4981],{"type":47,"value":4959},{"type":41,"tag":479,"props":4983,"children":4984},{"style":502},[4985],{"type":47,"value":4986}," usage",{"type":41,"tag":479,"props":4988,"children":4989},{"style":502},[4990],{"type":47,"value":4991}," from",{"type":41,"tag":479,"props":4993,"children":4994},{"style":502},[4995],{"type":47,"value":4996}," Java",{"type":41,"tag":479,"props":4998,"children":4999},{"style":502},[5000],{"type":47,"value":4468},{"type":41,"tag":479,"props":5002,"children":5003},{"class":481,"line":629},[5004,5009,5014,5019,5024,5028,5033,5038,5043,5048],{"type":41,"tag":479,"props":5005,"children":5006},{"style":496},[5007],{"type":47,"value":5008},"  --detect-versions",{"type":41,"tag":479,"props":5010,"children":5011},{"style":502},[5012],{"type":47,"value":5013},"      Detect",{"type":41,"tag":479,"props":5015,"children":5016},{"style":502},[5017],{"type":47,"value":5018}," OSGi",{"type":41,"tag":479,"props":5020,"children":5021},{"style":502},[5022],{"type":47,"value":5023}," versions",{"type":41,"tag":479,"props":5025,"children":5026},{"style":502},[5027],{"type":47,"value":4991},{"type":41,"tag":479,"props":5029,"children":5030},{"style":502},[5031],{"type":47,"value":5032}," existing",{"type":41,"tag":479,"props":5034,"children":5035},{"style":502},[5036],{"type":47,"value":5037}," deps",{"type":41,"tag":479,"props":5039,"children":5040},{"style":4417},[5041],{"type":47,"value":5042}," (default: ",{"type":41,"tag":479,"props":5044,"children":5045},{"style":502},[5046],{"type":47,"value":5047},"True",{"type":41,"tag":479,"props":5049,"children":5050},{"style":4417},[5051],{"type":47,"value":2018},{"type":41,"tag":479,"props":5053,"children":5054},{"class":481,"line":637},[5055],{"type":41,"tag":479,"props":5056,"children":5057},{"emptyLinePlaceholder":564},[5058],{"type":47,"value":567},{"type":41,"tag":479,"props":5060,"children":5061},{"class":481,"line":646},[5062],{"type":41,"tag":479,"props":5063,"children":5064},{"style":496},[5065],{"type":47,"value":4521},{"type":41,"tag":479,"props":5067,"children":5068},{"class":481,"line":692},[5069],{"type":41,"tag":479,"props":5070,"children":5071},{"style":486},[5072],{"type":47,"value":5073},"  # Migrate with automatic metatype detection\n",{"type":41,"tag":479,"props":5075,"children":5076},{"class":481,"line":700},[5077,5081,5085,5089],{"type":41,"tag":479,"props":5078,"children":5079},{"style":496},[5080],{"type":47,"value":4537},{"type":41,"tag":479,"props":5082,"children":5083},{"style":502},[5084],{"type":47,"value":1099},{"type":41,"tag":479,"props":5086,"children":5087},{"style":502},[5088],{"type":47,"value":752},{"type":41,"tag":479,"props":5090,"children":5091},{"style":502},[5092],{"type":47,"value":1143},{"type":41,"tag":479,"props":5094,"children":5095},{"class":481,"line":709},[5096],{"type":41,"tag":479,"props":5097,"children":5098},{"emptyLinePlaceholder":564},[5099],{"type":47,"value":567},{"type":41,"tag":479,"props":5101,"children":5102},{"class":481,"line":1520},[5103],{"type":41,"tag":479,"props":5104,"children":5105},{"style":486},[5106],{"type":47,"value":5107},"  # Dry run with validation\n",{"type":41,"tag":479,"props":5109,"children":5110},{"class":481,"line":1528},[5111,5115,5119,5123,5128],{"type":41,"tag":479,"props":5112,"children":5113},{"style":496},[5114],{"type":47,"value":4537},{"type":41,"tag":479,"props":5116,"children":5117},{"style":502},[5118],{"type":47,"value":1099},{"type":41,"tag":479,"props":5120,"children":5121},{"style":502},[5122],{"type":47,"value":752},{"type":41,"tag":479,"props":5124,"children":5125},{"style":502},[5126],{"type":47,"value":5127}," --dry-run",{"type":41,"tag":479,"props":5129,"children":5130},{"style":502},[5131],{"type":47,"value":863},{"type":41,"tag":479,"props":5133,"children":5134},{"class":481,"line":1536},[5135],{"type":41,"tag":479,"props":5136,"children":5137},{"emptyLinePlaceholder":564},[5138],{"type":47,"value":567},{"type":41,"tag":479,"props":5140,"children":5141},{"class":481,"line":1545},[5142],{"type":41,"tag":479,"props":5143,"children":5144},{"style":486},[5145],{"type":47,"value":4630},{"type":41,"tag":479,"props":5147,"children":5148},{"class":481,"line":1554},[5149,5153,5157],{"type":41,"tag":479,"props":5150,"children":5151},{"style":496},[5152],{"type":47,"value":4638},{"type":41,"tag":479,"props":5154,"children":5155},{"style":502},[5156],{"type":47,"value":4643},{"type":41,"tag":479,"props":5158,"children":5159},{"style":502},[5160],{"type":47,"value":5161}," pom.xml\n",{"type":41,"tag":451,"props":5163,"children":5165},{"id":5164},"testing",[5166],{"type":47,"value":5167},"Testing",{"type":41,"tag":50,"props":5169,"children":5170},{},[5171],{"type":47,"value":5172},"The skill includes comprehensive unit tests:",{"type":41,"tag":468,"props":5174,"children":5176},{"className":470,"code":5175,"language":472,"meta":473,"style":473},"# Run all tests\nbash scripts\u002Ftests\u002Frun_tests.sh\n\n# Run Java migration tests\npython3 scripts\u002Ftests\u002Ftest_migrate_annotations.py\n\n# Run POM migration tests\npython3 scripts\u002Ftests\u002Ftest_migrate_pom.py\n\n# Run constructor injection migration tests\npython3 scripts\u002Ftests\u002Ftest_migrate_constructor_injection.py\n",[5177],{"type":41,"tag":68,"props":5178,"children":5179},{"__ignoreMap":473},[5180,5188,5199,5206,5214,5226,5233,5241,5253,5260,5268],{"type":41,"tag":479,"props":5181,"children":5182},{"class":481,"line":482},[5183],{"type":41,"tag":479,"props":5184,"children":5185},{"style":486},[5186],{"type":47,"value":5187},"# Run all tests\n",{"type":41,"tag":479,"props":5189,"children":5190},{"class":481,"line":492},[5191,5195],{"type":41,"tag":479,"props":5192,"children":5193},{"style":496},[5194],{"type":47,"value":472},{"type":41,"tag":479,"props":5196,"children":5197},{"style":502},[5198],{"type":47,"value":2535},{"type":41,"tag":479,"props":5200,"children":5201},{"class":481,"line":508},[5202],{"type":41,"tag":479,"props":5203,"children":5204},{"emptyLinePlaceholder":564},[5205],{"type":47,"value":567},{"type":41,"tag":479,"props":5207,"children":5208},{"class":481,"line":526},[5209],{"type":41,"tag":479,"props":5210,"children":5211},{"style":486},[5212],{"type":47,"value":5213},"# Run Java migration tests\n",{"type":41,"tag":479,"props":5215,"children":5216},{"class":481,"line":560},[5217,5221],{"type":41,"tag":479,"props":5218,"children":5219},{"style":496},[5220],{"type":47,"value":813},{"type":41,"tag":479,"props":5222,"children":5223},{"style":502},[5224],{"type":47,"value":5225}," scripts\u002Ftests\u002Ftest_migrate_annotations.py\n",{"type":41,"tag":479,"props":5227,"children":5228},{"class":481,"line":570},[5229],{"type":41,"tag":479,"props":5230,"children":5231},{"emptyLinePlaceholder":564},[5232],{"type":47,"value":567},{"type":41,"tag":479,"props":5234,"children":5235},{"class":481,"line":579},[5236],{"type":41,"tag":479,"props":5237,"children":5238},{"style":486},[5239],{"type":47,"value":5240},"# Run POM migration tests\n",{"type":41,"tag":479,"props":5242,"children":5243},{"class":481,"line":629},[5244,5248],{"type":41,"tag":479,"props":5245,"children":5246},{"style":496},[5247],{"type":47,"value":813},{"type":41,"tag":479,"props":5249,"children":5250},{"style":502},[5251],{"type":47,"value":5252}," scripts\u002Ftests\u002Ftest_migrate_pom.py\n",{"type":41,"tag":479,"props":5254,"children":5255},{"class":481,"line":637},[5256],{"type":41,"tag":479,"props":5257,"children":5258},{"emptyLinePlaceholder":564},[5259],{"type":47,"value":567},{"type":41,"tag":479,"props":5261,"children":5262},{"class":481,"line":646},[5263],{"type":41,"tag":479,"props":5264,"children":5265},{"style":486},[5266],{"type":47,"value":5267},"# Run constructor injection migration tests\n",{"type":41,"tag":479,"props":5269,"children":5270},{"class":481,"line":692},[5271,5275],{"type":41,"tag":479,"props":5272,"children":5273},{"style":496},[5274],{"type":47,"value":813},{"type":41,"tag":479,"props":5276,"children":5277},{"style":502},[5278],{"type":47,"value":5279}," scripts\u002Ftests\u002Ftest_migrate_constructor_injection.py\n",{"type":41,"tag":50,"props":5281,"children":5282},{},[5283],{"type":47,"value":5284},"Test coverage includes:",{"type":41,"tag":91,"props":5286,"children":5287},{},[5288,5293,5298,5303,5308,5313,5318,5323,5328,5338,5348],{"type":41,"tag":95,"props":5289,"children":5290},{},[5291],{"type":47,"value":5292},"Property parsing and conversion",{"type":41,"tag":95,"props":5294,"children":5295},{},[5296],{"type":47,"value":5297},"Metatype configuration generation",{"type":41,"tag":95,"props":5299,"children":5300},{},[5301],{"type":47,"value":5302},"Sling annotation transformation",{"type":41,"tag":95,"props":5304,"children":5305},{},[5306],{"type":47,"value":5307},"Reference cardinality migration",{"type":41,"tag":95,"props":5309,"children":5310},{},[5311],{"type":47,"value":5312},"Complete file migration scenarios",{"type":41,"tag":95,"props":5314,"children":5315},{},[5316],{"type":47,"value":5317},"POM plugin and dependency updates",{"type":41,"tag":95,"props":5319,"children":5320},{},[5321],{"type":47,"value":5322},"Version detection",{"type":41,"tag":95,"props":5324,"children":5325},{},[5326],{"type":47,"value":5327},"Statistics tracking",{"type":41,"tag":95,"props":5329,"children":5330},{},[5331,5336],{"type":41,"tag":99,"props":5332,"children":5333},{},[5334],{"type":47,"value":5335},"Constructor injection migration",{"type":47,"value":5337}," (config and reference conversion)",{"type":41,"tag":95,"props":5339,"children":5340},{},[5341,5346],{"type":41,"tag":99,"props":5342,"children":5343},{},[5344],{"type":47,"value":5345},"Reference eligibility detection",{"type":47,"value":5347}," (mandatory\u002Foptional, static\u002Fdynamic)",{"type":41,"tag":95,"props":5349,"children":5350},{},[5351],{"type":41,"tag":99,"props":5352,"children":5353},{},[5354],{"type":47,"value":5355},"Field final modifier addition",{"type":41,"tag":56,"props":5357,"children":5359},{"id":5358},"migration-patterns",[5360],{"type":47,"value":5361},"Migration Patterns",{"type":41,"tag":451,"props":5363,"children":5365},{"id":5364},"pattern-1-basic-component-with-properties",[5366],{"type":47,"value":5367},"Pattern 1: Basic Component with Properties",{"type":41,"tag":468,"props":5369,"children":5371},{"className":1409,"code":5370,"language":14,"meta":473,"style":473},"\u002F\u002F Before\n@Component(immediate = true)\n@Service\n@Property(name = \"service.vendor\", value = \"Apache Software Foundation\")\n@Property(name = \"service.ranking\", intValue = 100)\npublic class MyService implements SomeInterface {\n}\n\n\u002F\u002F After (fully automated)\n@Component(\n    immediate = true,\n    service = SomeInterface.class,\n    property = {\n        \"service.vendor=Apache Software Foundation\",\n        \"service.ranking:Integer=100\"\n    }\n)\npublic class MyService implements SomeInterface {\n}\n",[5372],{"type":41,"tag":68,"props":5373,"children":5374},{"__ignoreMap":473},[5375,5382,5390,5398,5406,5414,5422,5429,5436,5444,5452,5460,5468,5476,5484,5492,5499,5506,5513],{"type":41,"tag":479,"props":5376,"children":5377},{"class":481,"line":482},[5378],{"type":41,"tag":479,"props":5379,"children":5380},{},[5381],{"type":47,"value":1978},{"type":41,"tag":479,"props":5383,"children":5384},{"class":481,"line":492},[5385],{"type":41,"tag":479,"props":5386,"children":5387},{},[5388],{"type":47,"value":5389},"@Component(immediate = true)\n",{"type":41,"tag":479,"props":5391,"children":5392},{"class":481,"line":508},[5393],{"type":41,"tag":479,"props":5394,"children":5395},{},[5396],{"type":47,"value":5397},"@Service\n",{"type":41,"tag":479,"props":5399,"children":5400},{"class":481,"line":526},[5401],{"type":41,"tag":479,"props":5402,"children":5403},{},[5404],{"type":47,"value":5405},"@Property(name = \"service.vendor\", value = \"Apache Software Foundation\")\n",{"type":41,"tag":479,"props":5407,"children":5408},{"class":481,"line":560},[5409],{"type":41,"tag":479,"props":5410,"children":5411},{},[5412],{"type":47,"value":5413},"@Property(name = \"service.ranking\", intValue = 100)\n",{"type":41,"tag":479,"props":5415,"children":5416},{"class":481,"line":570},[5417],{"type":41,"tag":479,"props":5418,"children":5419},{},[5420],{"type":47,"value":5421},"public class MyService implements SomeInterface {\n",{"type":41,"tag":479,"props":5423,"children":5424},{"class":481,"line":579},[5425],{"type":41,"tag":479,"props":5426,"children":5427},{},[5428],{"type":47,"value":1486},{"type":41,"tag":479,"props":5430,"children":5431},{"class":481,"line":629},[5432],{"type":41,"tag":479,"props":5433,"children":5434},{"emptyLinePlaceholder":564},[5435],{"type":47,"value":567},{"type":41,"tag":479,"props":5437,"children":5438},{"class":481,"line":637},[5439],{"type":41,"tag":479,"props":5440,"children":5441},{},[5442],{"type":47,"value":5443},"\u002F\u002F After (fully automated)\n",{"type":41,"tag":479,"props":5445,"children":5446},{"class":481,"line":646},[5447],{"type":41,"tag":479,"props":5448,"children":5449},{},[5450],{"type":47,"value":5451},"@Component(\n",{"type":41,"tag":479,"props":5453,"children":5454},{"class":481,"line":692},[5455],{"type":41,"tag":479,"props":5456,"children":5457},{},[5458],{"type":47,"value":5459},"    immediate = true,\n",{"type":41,"tag":479,"props":5461,"children":5462},{"class":481,"line":700},[5463],{"type":41,"tag":479,"props":5464,"children":5465},{},[5466],{"type":47,"value":5467},"    service = SomeInterface.class,\n",{"type":41,"tag":479,"props":5469,"children":5470},{"class":481,"line":709},[5471],{"type":41,"tag":479,"props":5472,"children":5473},{},[5474],{"type":47,"value":5475},"    property = {\n",{"type":41,"tag":479,"props":5477,"children":5478},{"class":481,"line":1520},[5479],{"type":41,"tag":479,"props":5480,"children":5481},{},[5482],{"type":47,"value":5483},"        \"service.vendor=Apache Software Foundation\",\n",{"type":41,"tag":479,"props":5485,"children":5486},{"class":481,"line":1528},[5487],{"type":41,"tag":479,"props":5488,"children":5489},{},[5490],{"type":47,"value":5491},"        \"service.ranking:Integer=100\"\n",{"type":41,"tag":479,"props":5493,"children":5494},{"class":481,"line":1536},[5495],{"type":41,"tag":479,"props":5496,"children":5497},{},[5498],{"type":47,"value":1478},{"type":41,"tag":479,"props":5500,"children":5501},{"class":481,"line":1545},[5502],{"type":41,"tag":479,"props":5503,"children":5504},{},[5505],{"type":47,"value":2018},{"type":41,"tag":479,"props":5507,"children":5508},{"class":481,"line":1554},[5509],{"type":41,"tag":479,"props":5510,"children":5511},{},[5512],{"type":47,"value":5421},{"type":41,"tag":479,"props":5514,"children":5515},{"class":481,"line":1563},[5516],{"type":41,"tag":479,"props":5517,"children":5518},{},[5519],{"type":47,"value":1486},{"type":41,"tag":451,"props":5521,"children":5523},{"id":5522},"pattern-2-configurable-component-with-component-property-types",[5524],{"type":47,"value":5525},"Pattern 2: Configurable Component with Component Property Types",{"type":41,"tag":468,"props":5527,"children":5529},{"className":1409,"code":5528,"language":14,"meta":473,"style":473},"\u002F\u002F Before - Using deprecated Map approach\n@Component(metatype = true, immediate = true, label = \"My Service\", description = \"Service description\")\n@Property(name = \"timeout\", intValue = 30, label = \"Timeout\", description = \"Request timeout\")\n@Property(name = \"retries\", intValue = 3, label = \"Retries\", description = \"Number of retries\")\npublic class MyService {\n    @Activate\n    private void activate(Map\u003CString, Object> props) {\n        int timeout = PropertiesUtil.toInteger(props.get(\"timeout\"), 30);\n        int retries = PropertiesUtil.toInteger(props.get(\"retries\"), 3);\n    }\n}\n\n\u002F\u002F After - Using Component Property Types (fully automated, type-safe)\n@Component(immediate = true)\n@Designate(ocd = MyService.Config.class)\npublic class MyService {\n\n    @ObjectClassDefinition(name = \"My Service\", description = \"Service description\")\n    public @interface Config {\n        @AttributeDefinition(name = \"Timeout\", description = \"Request timeout\")\n        int timeout() default 30;\n\n        @AttributeDefinition(name = \"Retries\", description = \"Number of retries\")\n        int retries() default 3;\n    }\n\n    @Activate\n    private void activate(Config config) {\n        \u002F\u002F Type-safe access - no conversion utilities needed!\n        int timeout = config.timeout();\n        int retries = config.retries();\n    }\n}\n",[5530],{"type":41,"tag":68,"props":5531,"children":5532},{"__ignoreMap":473},[5533,5540,5548,5556,5564,5571,5578,5585,5592,5600,5607,5614,5621,5629,5636,5643,5650,5657,5665,5672,5680,5687,5694,5702,5710,5717,5724,5731,5738,5746,5753,5761,5768],{"type":41,"tag":479,"props":5534,"children":5535},{"class":481,"line":482},[5536],{"type":41,"tag":479,"props":5537,"children":5538},{},[5539],{"type":47,"value":1422},{"type":41,"tag":479,"props":5541,"children":5542},{"class":481,"line":492},[5543],{"type":41,"tag":479,"props":5544,"children":5545},{},[5546],{"type":47,"value":5547},"@Component(metatype = true, immediate = true, label = \"My Service\", description = \"Service description\")\n",{"type":41,"tag":479,"props":5549,"children":5550},{"class":481,"line":508},[5551],{"type":41,"tag":479,"props":5552,"children":5553},{},[5554],{"type":47,"value":5555},"@Property(name = \"timeout\", intValue = 30, label = \"Timeout\", description = \"Request timeout\")\n",{"type":41,"tag":479,"props":5557,"children":5558},{"class":481,"line":526},[5559],{"type":41,"tag":479,"props":5560,"children":5561},{},[5562],{"type":47,"value":5563},"@Property(name = \"retries\", intValue = 3, label = \"Retries\", description = \"Number of retries\")\n",{"type":41,"tag":479,"props":5565,"children":5566},{"class":481,"line":560},[5567],{"type":41,"tag":479,"props":5568,"children":5569},{},[5570],{"type":47,"value":1446},{"type":41,"tag":479,"props":5572,"children":5573},{"class":481,"line":570},[5574],{"type":41,"tag":479,"props":5575,"children":5576},{},[5577],{"type":47,"value":1454},{"type":41,"tag":479,"props":5579,"children":5580},{"class":481,"line":579},[5581],{"type":41,"tag":479,"props":5582,"children":5583},{},[5584],{"type":47,"value":1462},{"type":41,"tag":479,"props":5586,"children":5587},{"class":481,"line":629},[5588],{"type":41,"tag":479,"props":5589,"children":5590},{},[5591],{"type":47,"value":1470},{"type":41,"tag":479,"props":5593,"children":5594},{"class":481,"line":637},[5595],{"type":41,"tag":479,"props":5596,"children":5597},{},[5598],{"type":47,"value":5599},"        int retries = PropertiesUtil.toInteger(props.get(\"retries\"), 3);\n",{"type":41,"tag":479,"props":5601,"children":5602},{"class":481,"line":646},[5603],{"type":41,"tag":479,"props":5604,"children":5605},{},[5606],{"type":47,"value":1478},{"type":41,"tag":479,"props":5608,"children":5609},{"class":481,"line":692},[5610],{"type":41,"tag":479,"props":5611,"children":5612},{},[5613],{"type":47,"value":1486},{"type":41,"tag":479,"props":5615,"children":5616},{"class":481,"line":700},[5617],{"type":41,"tag":479,"props":5618,"children":5619},{"emptyLinePlaceholder":564},[5620],{"type":47,"value":567},{"type":41,"tag":479,"props":5622,"children":5623},{"class":481,"line":709},[5624],{"type":41,"tag":479,"props":5625,"children":5626},{},[5627],{"type":47,"value":5628},"\u002F\u002F After - Using Component Property Types (fully automated, type-safe)\n",{"type":41,"tag":479,"props":5630,"children":5631},{"class":481,"line":1520},[5632],{"type":41,"tag":479,"props":5633,"children":5634},{},[5635],{"type":47,"value":5389},{"type":41,"tag":479,"props":5637,"children":5638},{"class":481,"line":1528},[5639],{"type":41,"tag":479,"props":5640,"children":5641},{},[5642],{"type":47,"value":1517},{"type":41,"tag":479,"props":5644,"children":5645},{"class":481,"line":1536},[5646],{"type":41,"tag":479,"props":5647,"children":5648},{},[5649],{"type":47,"value":1446},{"type":41,"tag":479,"props":5651,"children":5652},{"class":481,"line":1545},[5653],{"type":41,"tag":479,"props":5654,"children":5655},{"emptyLinePlaceholder":564},[5656],{"type":47,"value":567},{"type":41,"tag":479,"props":5658,"children":5659},{"class":481,"line":1554},[5660],{"type":41,"tag":479,"props":5661,"children":5662},{},[5663],{"type":47,"value":5664},"    @ObjectClassDefinition(name = \"My Service\", description = \"Service description\")\n",{"type":41,"tag":479,"props":5666,"children":5667},{"class":481,"line":1563},[5668],{"type":41,"tag":479,"props":5669,"children":5670},{},[5671],{"type":47,"value":1551},{"type":41,"tag":479,"props":5673,"children":5674},{"class":481,"line":1572},[5675],{"type":41,"tag":479,"props":5676,"children":5677},{},[5678],{"type":47,"value":5679},"        @AttributeDefinition(name = \"Timeout\", description = \"Request timeout\")\n",{"type":41,"tag":479,"props":5681,"children":5682},{"class":481,"line":1580},[5683],{"type":41,"tag":479,"props":5684,"children":5685},{},[5686],{"type":47,"value":1569},{"type":41,"tag":479,"props":5688,"children":5689},{"class":481,"line":1588},[5690],{"type":41,"tag":479,"props":5691,"children":5692},{"emptyLinePlaceholder":564},[5693],{"type":47,"value":567},{"type":41,"tag":479,"props":5695,"children":5696},{"class":481,"line":1596},[5697],{"type":41,"tag":479,"props":5698,"children":5699},{},[5700],{"type":47,"value":5701},"        @AttributeDefinition(name = \"Retries\", description = \"Number of retries\")\n",{"type":41,"tag":479,"props":5703,"children":5704},{"class":481,"line":1605},[5705],{"type":41,"tag":479,"props":5706,"children":5707},{},[5708],{"type":47,"value":5709},"        int retries() default 3;\n",{"type":41,"tag":479,"props":5711,"children":5712},{"class":481,"line":1614},[5713],{"type":41,"tag":479,"props":5714,"children":5715},{},[5716],{"type":47,"value":1478},{"type":41,"tag":479,"props":5718,"children":5719},{"class":481,"line":1623},[5720],{"type":41,"tag":479,"props":5721,"children":5722},{"emptyLinePlaceholder":564},[5723],{"type":47,"value":567},{"type":41,"tag":479,"props":5725,"children":5726},{"class":481,"line":1631},[5727],{"type":41,"tag":479,"props":5728,"children":5729},{},[5730],{"type":47,"value":1454},{"type":41,"tag":479,"props":5732,"children":5733},{"class":481,"line":3079},[5734],{"type":41,"tag":479,"props":5735,"children":5736},{},[5737],{"type":47,"value":1602},{"type":41,"tag":479,"props":5739,"children":5740},{"class":481,"line":3087},[5741],{"type":41,"tag":479,"props":5742,"children":5743},{},[5744],{"type":47,"value":5745},"        \u002F\u002F Type-safe access - no conversion utilities needed!\n",{"type":41,"tag":479,"props":5747,"children":5748},{"class":481,"line":3095},[5749],{"type":41,"tag":479,"props":5750,"children":5751},{},[5752],{"type":47,"value":1620},{"type":41,"tag":479,"props":5754,"children":5755},{"class":481,"line":3103},[5756],{"type":41,"tag":479,"props":5757,"children":5758},{},[5759],{"type":47,"value":5760},"        int retries = config.retries();\n",{"type":41,"tag":479,"props":5762,"children":5763},{"class":481,"line":26},[5764],{"type":41,"tag":479,"props":5765,"children":5766},{},[5767],{"type":47,"value":1478},{"type":41,"tag":479,"props":5769,"children":5770},{"class":481,"line":3118},[5771],{"type":41,"tag":479,"props":5772,"children":5773},{},[5774],{"type":47,"value":1486},{"type":41,"tag":50,"props":5776,"children":5777},{},[5778,5782],{"type":41,"tag":99,"props":5779,"children":5780},{},[5781],{"type":47,"value":441},{"type":47,"value":5783},": Component Property Types are the OSGi R7 best practice and are automatically generated by the migration.",{"type":41,"tag":451,"props":5785,"children":5787},{"id":5786},"pattern-3-sling-servlet",[5788],{"type":47,"value":5789},"Pattern 3: Sling Servlet",{"type":41,"tag":468,"props":5791,"children":5793},{"className":1409,"code":5792,"language":14,"meta":473,"style":473},"\u002F\u002F Before\n@SlingServlet(\n    resourceTypes = \"my\u002Fresource\u002Ftype\",\n    selectors = {\"print\", \"pdf\"},\n    extensions = \"html\"\n)\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n\n\u002F\u002F After (fully automated using Sling Servlets Annotations)\nimport org.apache.sling.servlets.annotations.SlingServletResourceTypes;\nimport org.osgi.service.component.annotations.Component;\nimport javax.servlet.Servlet;\n\n@Component(service = Servlet.class)\n@SlingServletResourceTypes(\n    resourceTypes = \"my\u002Fresource\u002Ftype\",\n    selectors = {\"print\", \"pdf\"},\n    extensions = \"html\"\n)\npublic class MyServlet extends SlingAllMethodsServlet {\n}\n",[5794],{"type":41,"tag":68,"props":5795,"children":5796},{"__ignoreMap":473},[5797,5804,5811,5818,5826,5834,5841,5848,5855,5862,5870,5878,5885,5892,5899,5906,5913,5920,5927,5934,5941,5948],{"type":41,"tag":479,"props":5798,"children":5799},{"class":481,"line":482},[5800],{"type":41,"tag":479,"props":5801,"children":5802},{},[5803],{"type":47,"value":1978},{"type":41,"tag":479,"props":5805,"children":5806},{"class":481,"line":492},[5807],{"type":41,"tag":479,"props":5808,"children":5809},{},[5810],{"type":47,"value":1986},{"type":41,"tag":479,"props":5812,"children":5813},{"class":481,"line":508},[5814],{"type":41,"tag":479,"props":5815,"children":5816},{},[5817],{"type":47,"value":2195},{"type":41,"tag":479,"props":5819,"children":5820},{"class":481,"line":526},[5821],{"type":41,"tag":479,"props":5822,"children":5823},{},[5824],{"type":47,"value":5825},"    selectors = {\"print\", \"pdf\"},\n",{"type":41,"tag":479,"props":5827,"children":5828},{"class":481,"line":560},[5829],{"type":41,"tag":479,"props":5830,"children":5831},{},[5832],{"type":47,"value":5833},"    extensions = \"html\"\n",{"type":41,"tag":479,"props":5835,"children":5836},{"class":481,"line":570},[5837],{"type":41,"tag":479,"props":5838,"children":5839},{},[5840],{"type":47,"value":2018},{"type":41,"tag":479,"props":5842,"children":5843},{"class":481,"line":579},[5844],{"type":41,"tag":479,"props":5845,"children":5846},{},[5847],{"type":47,"value":2026},{"type":41,"tag":479,"props":5849,"children":5850},{"class":481,"line":629},[5851],{"type":41,"tag":479,"props":5852,"children":5853},{},[5854],{"type":47,"value":1486},{"type":41,"tag":479,"props":5856,"children":5857},{"class":481,"line":637},[5858],{"type":41,"tag":479,"props":5859,"children":5860},{"emptyLinePlaceholder":564},[5861],{"type":47,"value":567},{"type":41,"tag":479,"props":5863,"children":5864},{"class":481,"line":646},[5865],{"type":41,"tag":479,"props":5866,"children":5867},{},[5868],{"type":47,"value":5869},"\u002F\u002F After (fully automated using Sling Servlets Annotations)\n",{"type":41,"tag":479,"props":5871,"children":5872},{"class":481,"line":692},[5873],{"type":41,"tag":479,"props":5874,"children":5875},{},[5876],{"type":47,"value":5877},"import org.apache.sling.servlets.annotations.SlingServletResourceTypes;\n",{"type":41,"tag":479,"props":5879,"children":5880},{"class":481,"line":700},[5881],{"type":41,"tag":479,"props":5882,"children":5883},{},[5884],{"type":47,"value":2064},{"type":41,"tag":479,"props":5886,"children":5887},{"class":481,"line":709},[5888],{"type":41,"tag":479,"props":5889,"children":5890},{},[5891],{"type":47,"value":2072},{"type":41,"tag":479,"props":5893,"children":5894},{"class":481,"line":1520},[5895],{"type":41,"tag":479,"props":5896,"children":5897},{"emptyLinePlaceholder":564},[5898],{"type":47,"value":567},{"type":41,"tag":479,"props":5900,"children":5901},{"class":481,"line":1528},[5902],{"type":41,"tag":479,"props":5903,"children":5904},{},[5905],{"type":47,"value":2087},{"type":41,"tag":479,"props":5907,"children":5908},{"class":481,"line":1536},[5909],{"type":41,"tag":479,"props":5910,"children":5911},{},[5912],{"type":47,"value":2187},{"type":41,"tag":479,"props":5914,"children":5915},{"class":481,"line":1545},[5916],{"type":41,"tag":479,"props":5917,"children":5918},{},[5919],{"type":47,"value":2195},{"type":41,"tag":479,"props":5921,"children":5922},{"class":481,"line":1554},[5923],{"type":41,"tag":479,"props":5924,"children":5925},{},[5926],{"type":47,"value":5825},{"type":41,"tag":479,"props":5928,"children":5929},{"class":481,"line":1563},[5930],{"type":41,"tag":479,"props":5931,"children":5932},{},[5933],{"type":47,"value":5833},{"type":41,"tag":479,"props":5935,"children":5936},{"class":481,"line":1572},[5937],{"type":41,"tag":479,"props":5938,"children":5939},{},[5940],{"type":47,"value":2018},{"type":41,"tag":479,"props":5942,"children":5943},{"class":481,"line":1580},[5944],{"type":41,"tag":479,"props":5945,"children":5946},{},[5947],{"type":47,"value":2026},{"type":41,"tag":479,"props":5949,"children":5950},{"class":481,"line":1588},[5951],{"type":41,"tag":479,"props":5952,"children":5953},{},[5954],{"type":47,"value":1486},{"type":41,"tag":56,"props":5956,"children":5958},{"id":5957},"reference-documentation",[5959],{"type":47,"value":5960},"Reference Documentation",{"type":41,"tag":50,"props":5962,"children":5963},{},[5964],{"type":47,"value":5965},"For comprehensive annotation mappings and examples:",{"type":41,"tag":468,"props":5967,"children":5969},{"className":470,"code":5968,"language":472,"meta":473,"style":473},"# View complete mapping reference\ncat references\u002Fannotation-mappings.md\n",[5970],{"type":41,"tag":68,"props":5971,"children":5972},{"__ignoreMap":473},[5973,5981],{"type":41,"tag":479,"props":5974,"children":5975},{"class":481,"line":482},[5976],{"type":41,"tag":479,"props":5977,"children":5978},{"style":486},[5979],{"type":47,"value":5980},"# View complete mapping reference\n",{"type":41,"tag":479,"props":5982,"children":5983},{"class":481,"line":492},[5984,5989],{"type":41,"tag":479,"props":5985,"children":5986},{"style":496},[5987],{"type":47,"value":5988},"cat",{"type":41,"tag":479,"props":5990,"children":5991},{"style":502},[5992],{"type":47,"value":5993}," references\u002Fannotation-mappings.md\n",{"type":41,"tag":50,"props":5995,"children":5996},{},[5997],{"type":47,"value":5998},"This includes:",{"type":41,"tag":91,"props":6000,"children":6001},{},[6002,6007,6012,6017,6022],{"type":41,"tag":95,"props":6003,"children":6004},{},[6005],{"type":47,"value":6006},"All annotation transformations with before\u002Fafter examples",{"type":41,"tag":95,"props":6008,"children":6009},{},[6010],{"type":47,"value":6011},"Cardinality and policy mappings",{"type":41,"tag":95,"props":6013,"children":6014},{},[6015],{"type":47,"value":6016},"Property type specifications",{"type":41,"tag":95,"props":6018,"children":6019},{},[6020],{"type":47,"value":6021},"Sling annotation patterns",{"type":41,"tag":95,"props":6023,"children":6024},{},[6025],{"type":47,"value":6026},"Common migration patterns",{"type":41,"tag":56,"props":6028,"children":6030},{"id":6029},"troubleshooting",[6031],{"type":47,"value":6032},"Troubleshooting",{"type":41,"tag":451,"props":6034,"children":6036},{"id":6035},"components-not-activating",[6037],{"type":47,"value":6038},"Components Not Activating",{"type":41,"tag":50,"props":6040,"children":6041},{},[6042],{"type":47,"value":6043},"Check:",{"type":41,"tag":91,"props":6045,"children":6046},{},[6047,6063,6068,6073],{"type":41,"tag":95,"props":6048,"children":6049},{},[6050,6056,6058],{"type":41,"tag":68,"props":6051,"children":6053},{"className":6052},[],[6054],{"type":47,"value":6055},"service",{"type":47,"value":6057}," attribute properly set in ",{"type":41,"tag":68,"props":6059,"children":6061},{"className":6060},[],[6062],{"type":47,"value":727},{"type":41,"tag":95,"props":6064,"children":6065},{},[6066],{"type":47,"value":6067},"All required dependencies satisfied",{"type":41,"tag":95,"props":6069,"children":6070},{},[6071],{"type":47,"value":6072},"No compilation errors",{"type":41,"tag":95,"props":6074,"children":6075},{},[6076,6078],{"type":47,"value":6077},"Run validation: ",{"type":41,"tag":68,"props":6079,"children":6081},{"className":6080},[],[6082],{"type":47,"value":6083},"python3 scripts\u002Fmigrate_annotations.py src\u002F --validate",{"type":41,"tag":451,"props":6085,"children":6087},{"id":6086},"configuration-not-working",[6088],{"type":47,"value":6089},"Configuration Not Working",{"type":41,"tag":91,"props":6091,"children":6092},{},[6093,6098,6111,6116],{"type":41,"tag":95,"props":6094,"children":6095},{},[6096],{"type":47,"value":6097},"Verify metatype annotations are present",{"type":41,"tag":95,"props":6099,"children":6100},{},[6101,6103,6109],{"type":47,"value":6102},"Check ",{"type":41,"tag":68,"props":6104,"children":6106},{"className":6105},[],[6107],{"type":47,"value":6108},"@Designate",{"type":47,"value":6110}," links to correct config interface",{"type":41,"tag":95,"props":6112,"children":6113},{},[6114],{"type":47,"value":6115},"Ensure activate method signature matches config type",{"type":41,"tag":95,"props":6117,"children":6118},{},[6119,6121,6127],{"type":47,"value":6120},"POM contains metatype dependency (auto-added with ",{"type":41,"tag":68,"props":6122,"children":6124},{"className":6123},[],[6125],{"type":47,"value":6126},"--auto-detect-metatype",{"type":47,"value":1062},{"type":41,"tag":451,"props":6129,"children":6131},{"id":6130},"build-failures",[6132],{"type":47,"value":6133},"Build Failures",{"type":41,"tag":91,"props":6135,"children":6136},{},[6137,6162,6167,6178],{"type":41,"tag":95,"props":6138,"children":6139},{},[6140,6142,6147,6148,6153,6155,6160],{"type":47,"value":6141},"Ensure OSGi bundle plugin (",{"type":41,"tag":68,"props":6143,"children":6145},{"className":6144},[],[6146],{"type":47,"value":1275},{"type":47,"value":1277},{"type":41,"tag":68,"props":6149,"children":6151},{"className":6150},[],[6152],{"type":47,"value":1283},{"type":47,"value":6154},") has ",{"type":41,"tag":68,"props":6156,"children":6158},{"className":6157},[],[6159],{"type":47,"value":1291},{"type":47,"value":6161}," (auto-fixed)",{"type":41,"tag":95,"props":6163,"children":6164},{},[6165],{"type":47,"value":6166},"Verify all OSGi annotation dependencies are present (auto-added)",{"type":41,"tag":95,"props":6168,"children":6169},{},[6170,6172],{"type":47,"value":6171},"Run POM validation: ",{"type":41,"tag":68,"props":6173,"children":6175},{"className":6174},[],[6176],{"type":47,"value":6177},"python3 scripts\u002Fmigrate_pom.py . --validate",{"type":41,"tag":95,"props":6179,"children":6180},{},[6181],{"type":47,"value":6182},"Check migration summary for errors and warnings",{"type":41,"tag":451,"props":6184,"children":6186},{"id":6185},"migration-issues",[6187],{"type":47,"value":6188},"Migration Issues",{"type":41,"tag":50,"props":6190,"children":6191},{},[6192],{"type":47,"value":6193},"If you encounter any issues:",{"type":41,"tag":1715,"props":6195,"children":6196},{},[6197,6207,6217,6227,6237],{"type":41,"tag":95,"props":6198,"children":6199},{},[6200,6205],{"type":41,"tag":99,"props":6201,"children":6202},{},[6203],{"type":47,"value":6204},"Review the statistics",{"type":47,"value":6206},": The summary shows exactly what was changed",{"type":41,"tag":95,"props":6208,"children":6209},{},[6210,6215],{"type":41,"tag":99,"props":6211,"children":6212},{},[6213],{"type":47,"value":6214},"Check warnings",{"type":47,"value":6216},": The script flags items that may need review",{"type":41,"tag":95,"props":6218,"children":6219},{},[6220,6225],{"type":41,"tag":99,"props":6221,"children":6222},{},[6223],{"type":47,"value":6224},"Use dry-run",{"type":47,"value":6226},": Preview changes before applying them",{"type":41,"tag":95,"props":6228,"children":6229},{},[6230,6235],{"type":41,"tag":99,"props":6231,"children":6232},{},[6233],{"type":47,"value":6234},"Run tests",{"type":47,"value":6236},": Use the included test suite to verify migration logic",{"type":41,"tag":95,"props":6238,"children":6239},{},[6240,6245,6246,6252],{"type":41,"tag":99,"props":6241,"children":6242},{},[6243],{"type":47,"value":6244},"Validate",{"type":47,"value":4362},{"type":41,"tag":68,"props":6247,"children":6249},{"className":6248},[],[6250],{"type":47,"value":6251},"--validate",{"type":47,"value":6253}," flag to check for common issues",{"type":41,"tag":56,"props":6255,"children":6257},{"id":6256},"performance",[6258],{"type":47,"value":6259},"Performance",{"type":41,"tag":50,"props":6261,"children":6262},{},[6263],{"type":47,"value":6264},"The enhanced migration scripts are optimized for large codebases:",{"type":41,"tag":91,"props":6266,"children":6267},{},[6268,6273,6278,6283],{"type":41,"tag":95,"props":6269,"children":6270},{},[6271],{"type":47,"value":6272},"Processes hundreds of files per second",{"type":41,"tag":95,"props":6274,"children":6275},{},[6276],{"type":47,"value":6277},"Memory-efficient line-by-line processing",{"type":41,"tag":95,"props":6279,"children":6280},{},[6281],{"type":47,"value":6282},"Parallel processing support (via multiple script invocations)",{"type":41,"tag":95,"props":6284,"children":6285},{},[6286],{"type":47,"value":6287},"Progress reporting for large projects",{"type":41,"tag":50,"props":6289,"children":6290},{},[6291],{"type":47,"value":6292},"Example performance:",{"type":41,"tag":91,"props":6294,"children":6295},{},[6296,6301,6306],{"type":41,"tag":95,"props":6297,"children":6298},{},[6299],{"type":47,"value":6300},"500 Java files: ~30 seconds",{"type":41,"tag":95,"props":6302,"children":6303},{},[6304],{"type":47,"value":6305},"1000 Java files: ~1 minute",{"type":41,"tag":95,"props":6307,"children":6308},{},[6309],{"type":47,"value":6310},"50 POM files: ~5 seconds",{"type":41,"tag":56,"props":6312,"children":6314},{"id":6313},"whats-new-in-enhanced-version",[6315],{"type":47,"value":6316},"What's New in Enhanced Version",{"type":41,"tag":451,"props":6318,"children":6320},{"id":6319},"version-21-features-latest",[6321],{"type":47,"value":6322},"Version 2.1 Features (Latest)",{"type":41,"tag":91,"props":6324,"children":6325},{},[6326,6337,6355,6366],{"type":41,"tag":95,"props":6327,"children":6328},{},[6329,6330,6335],{"type":47,"value":1652},{"type":41,"tag":99,"props":6331,"children":6332},{},[6333],{"type":47,"value":6334},"Constructor Injection Automation",{"type":47,"value":6336},": NEW! Automated Step 7 optimization for modern OSGi best practices",{"type":41,"tag":95,"props":6338,"children":6339},{},[6340,6341,6346,6348,6353],{"type":47,"value":1652},{"type":41,"tag":99,"props":6342,"children":6343},{},[6344],{"type":47,"value":6345},"Immutable Dependencies",{"type":47,"value":6347},": Automatically makes fields ",{"type":41,"tag":68,"props":6349,"children":6351},{"className":6350},[],[6352],{"type":47,"value":298},{"type":47,"value":6354}," when migrated to constructor",{"type":41,"tag":95,"props":6356,"children":6357},{},[6358,6359,6364],{"type":47,"value":1652},{"type":41,"tag":99,"props":6360,"children":6361},{},[6362],{"type":47,"value":6363},"Smart Reference Detection",{"type":47,"value":6365},": Identifies eligible vs ineligible references for constructor injection",{"type":41,"tag":95,"props":6367,"children":6368},{},[6369,6370,6375,6377,6382],{"type":47,"value":1652},{"type":41,"tag":99,"props":6371,"children":6372},{},[6373],{"type":47,"value":6374},"Config Parameter Migration",{"type":47,"value":6376},": Moves ",{"type":41,"tag":68,"props":6378,"children":6380},{"className":6379},[],[6381],{"type":47,"value":272},{"type":47,"value":274},{"type":41,"tag":451,"props":6384,"children":6386},{"id":6385},"version-20-features",[6387],{"type":47,"value":6388},"Version 2.0 Features",{"type":41,"tag":91,"props":6390,"children":6391},{},[6392,6403,6414,6425,6436,6447,6458,6469],{"type":41,"tag":95,"props":6393,"children":6394},{},[6395,6396,6401],{"type":47,"value":1652},{"type":41,"tag":99,"props":6397,"children":6398},{},[6399],{"type":47,"value":6400},"Full Property Migration",{"type":47,"value":6402},": Complete automation of @Property transformations",{"type":41,"tag":95,"props":6404,"children":6405},{},[6406,6407,6412],{"type":47,"value":1652},{"type":41,"tag":99,"props":6408,"children":6409},{},[6410],{"type":47,"value":6411},"Metatype Generation",{"type":47,"value":6413},": Automatic configuration interface creation",{"type":41,"tag":95,"props":6415,"children":6416},{},[6417,6418,6423],{"type":47,"value":1652},{"type":41,"tag":99,"props":6419,"children":6420},{},[6421],{"type":47,"value":6422},"Sling Automation",{"type":47,"value":6424},": Complete @SlingServlet and @SlingFilter migration",{"type":41,"tag":95,"props":6426,"children":6427},{},[6428,6429,6434],{"type":47,"value":1652},{"type":41,"tag":99,"props":6430,"children":6431},{},[6432],{"type":47,"value":6433},"Smart Version Detection",{"type":47,"value":6435},": Automatic OSGi version inference",{"type":41,"tag":95,"props":6437,"children":6438},{},[6439,6440,6445],{"type":47,"value":1652},{"type":41,"tag":99,"props":6441,"children":6442},{},[6443],{"type":47,"value":6444},"Comprehensive Validation",{"type":47,"value":6446},": Built-in checks for migration quality",{"type":41,"tag":95,"props":6448,"children":6449},{},[6450,6451,6456],{"type":47,"value":1652},{"type":41,"tag":99,"props":6452,"children":6453},{},[6454],{"type":47,"value":6455},"Detailed Reporting",{"type":47,"value":6457},": Statistics and warnings for all operations",{"type":41,"tag":95,"props":6459,"children":6460},{},[6461,6462,6467],{"type":47,"value":1652},{"type":41,"tag":99,"props":6463,"children":6464},{},[6465],{"type":47,"value":6466},"Test Suite",{"type":47,"value":6468},": Comprehensive unit and integration tests",{"type":41,"tag":95,"props":6470,"children":6471},{},[6472,6473,6478],{"type":47,"value":1652},{"type":41,"tag":99,"props":6474,"children":6475},{},[6476],{"type":47,"value":6477},"Error Recovery",{"type":47,"value":6479},": Graceful handling of edge cases",{"type":41,"tag":451,"props":6481,"children":6483},{"id":6482},"improvements-over-original",[6484],{"type":47,"value":6485},"Improvements Over Original",{"type":41,"tag":6487,"props":6488,"children":6489},"table",{},[6490,6519],{"type":41,"tag":6491,"props":6492,"children":6493},"thead",{},[6494],{"type":41,"tag":6495,"props":6496,"children":6497},"tr",{},[6498,6504,6509,6514],{"type":41,"tag":6499,"props":6500,"children":6501},"th",{},[6502],{"type":47,"value":6503},"Feature",{"type":41,"tag":6499,"props":6505,"children":6506},{},[6507],{"type":47,"value":6508},"Original",{"type":41,"tag":6499,"props":6510,"children":6511},{},[6512],{"type":47,"value":6513},"Enhanced",{"type":41,"tag":6499,"props":6515,"children":6516},{},[6517],{"type":47,"value":6518},"v2.1",{"type":41,"tag":6520,"props":6521,"children":6522},"tbody",{},[6523,6547,6569,6588,6613,6634,6656,6676,6698],{"type":41,"tag":6495,"props":6524,"children":6525},{},[6526,6532,6537,6542],{"type":41,"tag":6527,"props":6528,"children":6529},"td",{},[6530],{"type":47,"value":6531},"@Property Migration",{"type":41,"tag":6527,"props":6533,"children":6534},{},[6535],{"type":47,"value":6536},"TODO comments",{"type":41,"tag":6527,"props":6538,"children":6539},{},[6540],{"type":47,"value":6541},"Fully automated",{"type":41,"tag":6527,"props":6543,"children":6544},{},[6545],{"type":47,"value":6546},"✓",{"type":41,"tag":6495,"props":6548,"children":6549},{},[6550,6555,6560,6565],{"type":41,"tag":6527,"props":6551,"children":6552},{},[6553],{"type":47,"value":6554},"Metatype Support",{"type":41,"tag":6527,"props":6556,"children":6557},{},[6558],{"type":47,"value":6559},"Manual",{"type":41,"tag":6527,"props":6561,"children":6562},{},[6563],{"type":47,"value":6564},"Auto-generated",{"type":41,"tag":6527,"props":6566,"children":6567},{},[6568],{"type":47,"value":6546},{"type":41,"tag":6495,"props":6570,"children":6571},{},[6572,6576,6580,6584],{"type":41,"tag":6527,"props":6573,"children":6574},{},[6575],{"type":47,"value":246},{"type":41,"tag":6527,"props":6577,"children":6578},{},[6579],{"type":47,"value":6536},{"type":41,"tag":6527,"props":6581,"children":6582},{},[6583],{"type":47,"value":6541},{"type":41,"tag":6527,"props":6585,"children":6586},{},[6587],{"type":47,"value":6546},{"type":41,"tag":6495,"props":6589,"children":6590},{},[6591,6596,6601,6606],{"type":41,"tag":6527,"props":6592,"children":6593},{},[6594],{"type":47,"value":6595},"Constructor Injection",{"type":41,"tag":6527,"props":6597,"children":6598},{},[6599],{"type":47,"value":6600},"Not available",{"type":41,"tag":6527,"props":6602,"children":6603},{},[6604],{"type":47,"value":6605},"Manual guidance",{"type":41,"tag":6527,"props":6607,"children":6608},{},[6609],{"type":41,"tag":99,"props":6610,"children":6611},{},[6612],{"type":47,"value":6541},{"type":41,"tag":6495,"props":6614,"children":6615},{},[6616,6620,6625,6630],{"type":41,"tag":6527,"props":6617,"children":6618},{},[6619],{"type":47,"value":323},{"type":41,"tag":6527,"props":6621,"children":6622},{},[6623],{"type":47,"value":6624},"None",{"type":41,"tag":6527,"props":6626,"children":6627},{},[6628],{"type":47,"value":6629},"Comprehensive",{"type":41,"tag":6527,"props":6631,"children":6632},{},[6633],{"type":47,"value":6546},{"type":41,"tag":6495,"props":6635,"children":6636},{},[6637,6642,6647,6652],{"type":41,"tag":6527,"props":6638,"children":6639},{},[6640],{"type":47,"value":6641},"Reporting",{"type":41,"tag":6527,"props":6643,"children":6644},{},[6645],{"type":47,"value":6646},"Basic",{"type":41,"tag":6527,"props":6648,"children":6649},{},[6650],{"type":47,"value":6651},"Detailed stats",{"type":41,"tag":6527,"props":6653,"children":6654},{},[6655],{"type":47,"value":6546},{"type":41,"tag":6495,"props":6657,"children":6658},{},[6659,6663,6667,6672],{"type":41,"tag":6527,"props":6660,"children":6661},{},[6662],{"type":47,"value":5167},{"type":41,"tag":6527,"props":6664,"children":6665},{},[6666],{"type":47,"value":6624},{"type":41,"tag":6527,"props":6668,"children":6669},{},[6670],{"type":47,"value":6671},"Full test suite",{"type":41,"tag":6527,"props":6673,"children":6674},{},[6675],{"type":47,"value":6513},{"type":41,"tag":6495,"props":6677,"children":6678},{},[6679,6684,6689,6694],{"type":41,"tag":6527,"props":6680,"children":6681},{},[6682],{"type":47,"value":6683},"Version Detection",{"type":41,"tag":6527,"props":6685,"children":6686},{},[6687],{"type":47,"value":6688},"Hardcoded",{"type":41,"tag":6527,"props":6690,"children":6691},{},[6692],{"type":47,"value":6693},"Smart detection",{"type":41,"tag":6527,"props":6695,"children":6696},{},[6697],{"type":47,"value":6546},{"type":41,"tag":6495,"props":6699,"children":6700},{},[6701,6706,6710,6715],{"type":41,"tag":6527,"props":6702,"children":6703},{},[6704],{"type":47,"value":6705},"Error Handling",{"type":41,"tag":6527,"props":6707,"children":6708},{},[6709],{"type":47,"value":6646},{"type":41,"tag":6527,"props":6711,"children":6712},{},[6713],{"type":47,"value":6714},"Robust",{"type":41,"tag":6527,"props":6716,"children":6717},{},[6718],{"type":47,"value":6546},{"type":41,"tag":56,"props":6720,"children":6722},{"id":6721},"additional-resources",[6723],{"type":47,"value":6724},"Additional Resources",{"type":41,"tag":91,"props":6726,"children":6727},{},[6728,6733,6738,6743,6755,6766],{"type":41,"tag":95,"props":6729,"children":6730},{},[6731],{"type":47,"value":6732},"OSGi Compendium Specification: Component annotations (Chapter 112)",{"type":41,"tag":95,"props":6734,"children":6735},{},[6736],{"type":47,"value":6737},"Apache Felix SCR documentation",{"type":41,"tag":95,"props":6739,"children":6740},{},[6741],{"type":47,"value":6742},"Sling development documentation for servlet\u002Ffilter annotations",{"type":41,"tag":95,"props":6744,"children":6745},{},[6746,6748],{"type":47,"value":6747},"Apache Sling Servlets Annotations: ",{"type":41,"tag":2339,"props":6749,"children":6753},{"href":6750,"rel":6751},"https:\u002F\u002Fgithub.com\u002Fapache\u002Fsling-org-apache-sling-servlets-annotations",[6752],"nofollow",[6754],{"type":47,"value":6750},{"type":41,"tag":95,"props":6756,"children":6757},{},[6758,6760],{"type":47,"value":6759},"Test suite: ",{"type":41,"tag":68,"props":6761,"children":6763},{"className":6762},[],[6764],{"type":47,"value":6765},"scripts\u002Ftests\u002F",{"type":41,"tag":95,"props":6767,"children":6768},{},[6769,6771],{"type":47,"value":6770},"Example transformations: ",{"type":41,"tag":68,"props":6772,"children":6774},{"className":6773},[],[6775],{"type":47,"value":2341},{"type":41,"tag":56,"props":6777,"children":6779},{"id":6778},"sling-specific-features",[6780],{"type":47,"value":6781},"Sling-Specific Features",{"type":41,"tag":50,"props":6783,"children":6784},{},[6785,6787,6792],{"type":47,"value":6786},"For ",{"type":41,"tag":99,"props":6788,"children":6789},{},[6790],{"type":47,"value":6791},"Apache Sling projects",{"type":47,"value":6793},", the migration provides full automation:",{"type":41,"tag":1715,"props":6795,"children":6796},{},[6797,6853,6893],{"type":41,"tag":95,"props":6798,"children":6799},{},[6800,6805,6807],{"type":41,"tag":99,"props":6801,"children":6802},{},[6803],{"type":47,"value":6804},"Automatic Detection",{"type":47,"value":6806},": The migration automatically detects Sling servlet and filter usage by scanning your Java files for:",{"type":41,"tag":91,"props":6808,"children":6809},{},[6810,6820,6829],{"type":41,"tag":95,"props":6811,"children":6812},{},[6813,6818],{"type":41,"tag":68,"props":6814,"children":6816},{"className":6815},[],[6817],{"type":47,"value":1015},{"type":47,"value":6819}," annotations",{"type":41,"tag":95,"props":6821,"children":6822},{},[6823,6828],{"type":41,"tag":68,"props":6824,"children":6826},{"className":6825},[],[6827],{"type":47,"value":1032},{"type":47,"value":6819},{"type":41,"tag":95,"props":6830,"children":6831},{},[6832,6834,6839,6840,6845,6847,6852],{"type":47,"value":6833},"Existing ",{"type":41,"tag":68,"props":6835,"children":6837},{"className":6836},[],[6838],{"type":47,"value":2125},{"type":47,"value":111},{"type":41,"tag":68,"props":6841,"children":6843},{"className":6842},[],[6844],{"type":47,"value":2164},{"type":47,"value":6846},", or ",{"type":41,"tag":68,"props":6848,"children":6850},{"className":6849},[],[6851],{"type":47,"value":2241},{"type":47,"value":6819},{"type":41,"tag":95,"props":6854,"children":6855},{},[6856,6861,6863],{"type":41,"tag":99,"props":6857,"children":6858},{},[6859],{"type":47,"value":6860},"Dependency Management",{"type":47,"value":6862},": When Sling usage is detected, the migration automatically:",{"type":41,"tag":91,"props":6864,"children":6865},{},[6866,6876,6881],{"type":41,"tag":95,"props":6867,"children":6868},{},[6869,6870,6875],{"type":47,"value":2314},{"type":41,"tag":68,"props":6871,"children":6873},{"className":6872},[],[6874],{"type":47,"value":2320},{"type":47,"value":2322},{"type":41,"tag":95,"props":6877,"children":6878},{},[6879],{"type":47,"value":6880},"Places it after OSGi component and metatype dependencies",{"type":41,"tag":95,"props":6882,"children":6883},{},[6884,6886,6892],{"type":47,"value":6885},"Sets the correct scope (",{"type":41,"tag":68,"props":6887,"children":6889},{"className":6888},[],[6890],{"type":47,"value":6891},"provided",{"type":47,"value":1062},{"type":41,"tag":95,"props":6894,"children":6895},{},[6896,6901,6903,6936,6940],{"type":41,"tag":99,"props":6897,"children":6898},{},[6899],{"type":47,"value":6900},"Type-Safe Transformations",{"type":47,"value":6902},": The migration uses type-safe Sling Servlets Annotations:",{"type":41,"tag":91,"props":6904,"children":6905},{},[6906,6916,6926],{"type":41,"tag":95,"props":6907,"children":6908},{},[6909,6914],{"type":41,"tag":68,"props":6910,"children":6912},{"className":6911},[],[6913],{"type":47,"value":2125},{"type":47,"value":6915}," for path-based servlets",{"type":41,"tag":95,"props":6917,"children":6918},{},[6919,6924],{"type":41,"tag":68,"props":6920,"children":6922},{"className":6921},[],[6923],{"type":47,"value":2164},{"type":47,"value":6925}," for resource-type-based servlets with selectors, extensions, and methods",{"type":41,"tag":95,"props":6927,"children":6928},{},[6929,6934],{"type":41,"tag":68,"props":6930,"children":6932},{"className":6931},[],[6933],{"type":47,"value":2241},{"type":47,"value":6935}," for filters with scope, order, and pattern",{"type":41,"tag":6937,"props":6938,"children":6939},"br",{},[],{"type":47,"value":6941},"This provides better IDE support, compile-time validation, and improved readability compared to property strings.",{"type":41,"tag":50,"props":6943,"children":6944},{},[6945,6946,6952],{"type":47,"value":2337},{"type":41,"tag":2339,"props":6947,"children":6949},{"href":6948},"references\u002Fannotation-mappings.md#sling-annotations",[6950],{"type":47,"value":6951},"Sling annotation examples",{"type":47,"value":6953}," for detailed transformation syntax.",{"type":41,"tag":56,"props":6955,"children":6957},{"id":6956},"notes",[6958],{"type":47,"value":6959},"Notes",{"type":41,"tag":91,"props":6961,"children":6962},{},[6963,6975,6980,6985,6995,7006,7011],{"type":41,"tag":95,"props":6964,"children":6965},{},[6966,6968,6973],{"type":47,"value":6967},"The migration scripts now handle ",{"type":41,"tag":99,"props":6969,"children":6970},{},[6971],{"type":47,"value":6972},"98%+ of migrations automatically",{"type":47,"value":6974}," (including Step 7 constructor injection!)",{"type":41,"tag":95,"props":6976,"children":6977},{},[6978],{"type":47,"value":6979},"Manual review is only needed for very complex edge cases",{"type":41,"tag":95,"props":6981,"children":6982},{},[6983],{"type":47,"value":6984},"Always test in a development environment before production deployment",{"type":41,"tag":95,"props":6986,"children":6987},{},[6988,6993],{"type":41,"tag":99,"props":6989,"children":6990},{},[6991],{"type":47,"value":6992},"Java 17+ is required",{"type":47,"value":6994}," for OSGi R6\u002FR7 Component annotations (this is a prerequisite, not optional)",{"type":41,"tag":95,"props":6996,"children":6997},{},[6998,7000],{"type":47,"value":6999},"Run the test suite to verify migration logic: ",{"type":41,"tag":68,"props":7001,"children":7003},{"className":7002},[],[7004],{"type":47,"value":7005},"bash scripts\u002Ftests\u002Frun_tests.sh",{"type":41,"tag":95,"props":7007,"children":7008},{},[7009],{"type":47,"value":7010},"Some runtime behavior may differ subtly between SCR and R6+ implementations",{"type":41,"tag":95,"props":7012,"children":7013},{},[7014,7019],{"type":41,"tag":99,"props":7015,"children":7016},{},[7017],{"type":47,"value":7018},"Step 7 is optional",{"type":47,"value":7020}," but recommended - the automated script makes it easy and safe to apply",{"type":41,"tag":7022,"props":7023,"children":7024},"style",{},[7025],{"type":47,"value":7026},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":7028,"total":7179},[7029,7047,7063,7074,7087,7100,7116,7127,7137,7148,7158,7168],{"slug":7030,"name":7030,"fn":7031,"description":7032,"org":7033,"tags":7034,"stars":7044,"repoUrl":7045,"updatedAt":7046},"datafusion-python","write Apache DataFusion Python code","Use when the user is writing datafusion-python (Apache DataFusion Python bindings) DataFrame or SQL code. Covers imports, data loading, DataFrame operations, expression building, SQL-to-DataFrame mappings, idiomatic patterns, and common pitfalls.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7035,7038,7041],{"name":7036,"slug":7037,"type":15},"Data Analysis","data-analysis",{"name":7039,"slug":7040,"type":15},"Python","python",{"name":7042,"slug":7043,"type":15},"SQL","sql",593,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fdatafusion-python","2026-07-12T08:36:04.957626",{"slug":7048,"name":7048,"fn":7049,"description":7050,"org":7051,"tags":7052,"stars":7060,"repoUrl":7061,"updatedAt":7062},"bydbql","generate and execute BanyanDB BydbQL queries","Generate, validate, and optionally execute read-only BanyanDB BydbQL for STREAM, MEASURE, TRACE, and PROPERTY resources. Use when the user asks to query BanyanDB, translate natural language to BydbQL, inspect BanyanDB schema or data, validate BydbQL, or fetch raw BanyanDB records.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7053,7056,7059],{"name":7054,"slug":7055,"type":15},"Analytics","analytics",{"name":7057,"slug":7058,"type":15},"Database","database",{"name":7042,"slug":7043,"type":15},344,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fskywalking-banyandb","2026-07-12T08:31:01.294423",{"slug":7064,"name":7064,"fn":7065,"description":7066,"org":7067,"tags":7068,"stars":7060,"repoUrl":7061,"updatedAt":7073},"compiling","compile and build BanyanDB projects","Compile and build the SkyWalking BanyanDB project. Use when the user asks to compile, build, or generate code for this project.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7069,7072],{"name":7070,"slug":7071,"type":15},"Build","build",{"name":20,"slug":21,"type":15},"2026-07-12T08:31:06.373309",{"slug":7075,"name":7075,"fn":7076,"description":7077,"org":7078,"tags":7079,"stars":7060,"repoUrl":7061,"updatedAt":7086},"gh-pull-request","create GitHub pull requests for BanyanDB","Create a GitHub pull request for SkyWalking BanyanDB. Use when the user asks to create a PR, submit changes, or open a pull request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7080,7083],{"name":7081,"slug":7082,"type":15},"GitHub","github",{"name":7084,"slug":7085,"type":15},"Pull Requests","pull-requests","2026-07-12T08:31:03.792415",{"slug":7088,"name":7088,"fn":7089,"description":7090,"org":7091,"tags":7092,"stars":7060,"repoUrl":7061,"updatedAt":7099},"vendor-update","update Go and Node.js vendor dependencies","Upgrade Go\u002FNode.js vendor dependencies and sync tool versions. Use whenever the user says \"upgrade dependencies\", \"update vendors\", \"vendor update\", \"run vendor-upgrade\", \"bump dependencies\", \"update packages\", or asks to run the `vendor-update` Make target. This skill also checks `scripts\u002Fbuild\u002Fversion.mk` after upgrading to see if any tracked tool versions need updating too, and removes stale binaries from `bin\u002F` when versions change.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7093,7096],{"name":7094,"slug":7095,"type":15},"Go","go",{"name":7097,"slug":7098,"type":15},"Node.js","node-js","2026-07-12T08:31:02.555555",{"slug":7101,"name":7101,"fn":7102,"description":7103,"org":7104,"tags":7105,"stars":7113,"repoUrl":7114,"updatedAt":7115},"cayenne-cgen","generate Cayenne entity Java classes","Use this skill whenever the user wants to (re)generate Cayenne entity Java classes from a DataMap. Trigger on phrases like 'generate Java classes', 'regenerate entities', 'run cgen', 'create the entity classes', 'why is the Artist class missing fields', 'where did the `_Abstract*` classes come from', 'sync the entity classes with the model', or any request to materialize Java from the DataMap. Also trigger as a follow-up after modeling changes (someone added an entity, attribute, or relationship and now the Java side is stale). This skill exclusively uses the `mcp__cayenne__cgen_run` MCP tool — it does NOT use `mvn cayenne:cgen` or the Gradle cgen task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7106,7109,7110],{"name":7107,"slug":7108,"type":15},"Data Modeling","data-modeling",{"name":13,"slug":14,"type":15},{"name":7111,"slug":7112,"type":15},"ORM","orm",343,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fcayenne","2026-07-12T08:32:33.575211",{"slug":7117,"name":7117,"fn":7118,"description":7119,"org":7120,"tags":7121,"stars":7113,"repoUrl":7114,"updatedAt":7126},"cayenne-db-import","import database schema into Cayenne DataMaps","Use this skill when the user wants to import database schema metadata into a Cayenne DataMap — the *model\u002Fmapping only*, not names or Java classes. Trigger on phrases like 'reverse engineer the database', 'import the schema', 'generate a DataMap from my DB', 'add the new tables from the DB into the model', 'import the customer table', 'create entities from these tables', or any request to read database metadata to populate or update a DataMap's XML. This is for *full schema* or *bulk table* import; one-off a-la-carte entity additions belong in the cayenne-modeling skill. IMPORTANT — scope: this imports the mapping ONLY; it does not clean up the Object-layer names or (re)generate Java classes. When the user wants their whole project brought in line with the DB ('sync my project with the database', 'my schema changed, update everything', 'update my entities\u002Fclasses from the DB'), that is the end-to-end `cayenne-full-db-sync` skill, which runs this import and then name cleanup and class generation. To regenerate classes alone use `cayenne-cgen`. The skill runs reverse engineering directly via the `mcp__cayenne__dbimport_run` MCP tool when a DBConnector is already configured; otherwise it opens the CayenneModeler GUI via `mcp__cayenne__open_project` to configure the connection first.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7122,7123,7124,7125],{"name":7057,"slug":7058,"type":15},{"name":13,"slug":14,"type":15},{"name":7111,"slug":7112,"type":15},{"name":7042,"slug":7043,"type":15},"2026-07-19T05:40:33.655062",{"slug":7128,"name":7128,"fn":7129,"description":7130,"org":7131,"tags":7132,"stars":7113,"repoUrl":7114,"updatedAt":7136},"cayenne-full-db-sync","synchronize Cayenne projects with database","Use this skill when the user wants to bring their WHOLE Cayenne project in line with the database in one shot — the mapping, the Object-layer names, and the generated Java classes together. This is the end-to-end 'sync with the DB' workflow, and it orchestrates three skills in order: `cayenne-db-import` (import schema metadata into the DataMap) → `cayenne-model-naming` (polish the just-imported names) → `cayenne-cgen` (regenerate Java classes). Trigger on holistic phrases like 'sync my project with the database', 'sync with the DB', 'my schema changed, update everything', 'update my entities\u002Fclasses from the database', 'reverse engineer and regenerate the classes', 'import the new tables and rebuild the entities', 'full DB sync', 'bring the model and classes up to date with the DB'. The distinguishing signal is scope: the user wants the whole project (mapping + names + Java code), not just one stage. For the *model\u002Fmapping only* (no name cleanup, no class generation) use `cayenne-db-import`; to (re)generate classes alone use `cayenne-cgen`; to clean names alone use `cayenne-model-naming`. Uses the `mcp__cayenne__dbimport_run` and `mcp__cayenne__cgen_run` MCP tools via the sub-skills; does NOT use Maven or Gradle goals.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7133,7134,7135],{"name":7057,"slug":7058,"type":15},{"name":13,"slug":14,"type":15},{"name":7111,"slug":7112,"type":15},"2026-07-19T06:03:49.112969",{"slug":7138,"name":7138,"fn":7139,"description":7140,"org":7141,"tags":7142,"stars":7113,"repoUrl":7114,"updatedAt":7147},"cayenne-model-naming","clean up Cayenne object-layer names","Use this skill to clean up Object-layer names in a Cayenne DataMap — ObjEntity, ObjAttribute, and ObjRelationship names, plus DbRelationship names (the first-class unit of relationship cleanup — every FK has one whether or not an ObjRelationship was generated; the ObjRelationship name is synced to it when one exists) — so they read as descriptive, consistent Java. Trigger on phrases like 'clean up the model names', 'fix the entity names', 'these names look ugly', 'make the names descriptive', 'normalize the ObjEntity\u002Fattribute\u002Frelationship names', 'why is this relationship called team1', 'rename entities to be consistent', 'the import produced Gametype instead of GameType'. Invoke it on an explicit user request, or as a manual follow-up after a `cayenne-db-import` to polish the just-imported additions — it is never triggered automatically. IMPORTANT: this is a LIGHT polish pass — CayenneModeler's reverse-engineering already produces good names for the common case; only improve the specific things its deterministic algorithm cannot (run-together names with no separators like `gametype`, meaningless numbered names like `team1` from multiple relationships between two tables, and a common entity prefix that leaks into relationship names like `aaOrders`). Do NOT rewrite names that are already correct. This is Obj-layer naming polish; for structural model edits use `cayenne-modeling`, and for regenerating classes afterward use `cayenne-cgen`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7143,7144,7145,7146],{"name":7107,"slug":7108,"type":15},{"name":7057,"slug":7058,"type":15},{"name":13,"slug":14,"type":15},{"name":7111,"slug":7112,"type":15},"2026-07-22T05:35:32.342548",{"slug":7149,"name":7149,"fn":7150,"description":7151,"org":7152,"tags":7153,"stars":7113,"repoUrl":7114,"updatedAt":7157},"cayenne-modeler","manage Cayenne projects with CayenneModeler","Use this skill when the user explicitly wants to open CayenneModeler (the GUI) on a Cayenne project, or when the modeling task is inherently visual — reverse engineering (delegated to cayenne-db-import), bulk relationship layout, multi-entity visual refactoring. Trigger on phrases like 'open the Modeler', 'open in CayenneModeler', 'launch the GUI', 'edit visually', 'show me the project in the Modeler'. Do NOT trigger as a fallback for ordinary a-la-carte XML edits — those belong in the cayenne-modeling skill, which is faster and doesn't require the user to context-switch.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7154,7155,7156],{"name":7107,"slug":7108,"type":15},{"name":13,"slug":14,"type":15},{"name":7111,"slug":7112,"type":15},"2026-07-12T08:32:37.199428",{"slug":7159,"name":7159,"fn":7160,"description":7161,"org":7162,"tags":7163,"stars":7113,"repoUrl":7114,"updatedAt":7167},"cayenne-modeling","edit and extend Cayenne ORM models","Use this skill whenever the user wants to edit, inspect, or extend the Cayenne ORM model in a project — adding or modifying entities, attributes, relationships, embeddables, named queries, stored procedures, or DataNodes. Trigger on phrases like 'add an ObjEntity', 'add a DbEntity', 'add a relationship', 'expose this column as an attribute', 'create a new DataMap', 'add a named query', 'create an embeddable', 'add a stored procedure', 'change the attribute type', 'mark this column as nullable', 'rename this entity', or any mention of a Cayenne `*.map.xml` or `cayenne-*.xml` file. Also trigger when the user references modeling concepts (ObjEntity, DbEntity, ObjAttribute, DbAttribute, ObjRelationship, DbRelationship, Embeddable, dbEntityName, deleteRule, db-attribute-path, db-relationship-path, defaultPackage) in the context of a Cayenne-using app. This is the *primary* skill for a-la-carte ORM model manipulation — direct XML edits, not the Modeler GUI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7164,7165,7166],{"name":7057,"slug":7058,"type":15},{"name":13,"slug":14,"type":15},{"name":7111,"slug":7112,"type":15},"2026-07-19T05:40:32.6889",{"slug":7169,"name":7169,"fn":7170,"description":7171,"org":7172,"tags":7173,"stars":7113,"repoUrl":7114,"updatedAt":7178},"cayenne-query","write and modify Cayenne database queries","Use this skill whenever the user wants to write or modify a Cayenne query — fetching entities by criteria, joining, prefetching to avoid N+1, ordering, paginating, aggregating, or running raw SQL through Cayenne. Trigger on phrases like 'query for X', 'fetch all artists where ...', 'write an ObjectSelect', 'use SQLSelect', 'use SelectById', 'add a prefetch', 'get distinct values', 'count rows', 'find by ID', 'load by primary key', 'build a Cayenne expression', 'why am I getting N+1', 'how do I paginate', 'select a single column', 'select columns into a DTO', 'named query in the DataMap'. Do NOT trigger for modeling changes (use cayenne-modeling) or runtime bootstrap (use cayenne-runtime).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7174,7175,7176,7177],{"name":7057,"slug":7058,"type":15},{"name":13,"slug":14,"type":15},{"name":7111,"slug":7112,"type":15},{"name":7042,"slug":7043,"type":15},"2026-07-12T08:32:35.072322",108,{"items":7181,"total":508},[7182,7188,7207],{"slug":4,"name":4,"fn":5,"description":6,"org":7183,"tags":7184,"stars":22,"repoUrl":23,"updatedAt":24},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7185,7186,7187],{"name":20,"slug":21,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":7189,"name":7189,"fn":7190,"description":7191,"org":7192,"tags":7193,"stars":22,"repoUrl":23,"updatedAt":7206},"sling-release","automate Apache Sling project releases","Automates releasing an Apache Sling project end-to-end using Maven and the sling-cli Docker tool. Use when the user wants to release a Sling project, start a release, perform any step of the Apache Sling release process, or asks about releasing\u002Fvoting\u002Fpromoting a Sling module.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7194,7197,7200,7203],{"name":7195,"slug":7196,"type":15},"CLI","cli",{"name":7198,"slug":7199,"type":15},"Deployment","deployment",{"name":7201,"slug":7202,"type":15},"Docker","docker",{"name":7204,"slug":7205,"type":15},"Maven","maven","2026-07-12T08:32:48.18062",{"slug":7208,"name":7208,"fn":7209,"description":7210,"org":7211,"tags":7212,"stars":22,"repoUrl":23,"updatedAt":7216},"update-sling-parent-pom","upgrade Sling parent POM versions","Use when the user asks to upgrade the Sling parent POM version in their project",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[7213,7214,7215],{"name":20,"slug":21,"type":15},{"name":13,"slug":14,"type":15},{"name":7204,"slug":7205,"type":15},"2026-07-29T05:38:51.809245"]