2.2: AL Configuration Files: app.json & launch.json Parameters
Key Takeaways
- app.json serves as the extension manifest, defining unique GUID identity, name, publisher, semantic version, runtime level, target platform (Cloud vs OnPrem), and object ID ranges.
- The idRanges property restricts which object IDs can be authored within the extension; declaring an object outside these intervals is a fatal compilation error.
- The resourceExposurePolicy in app.json governs intellectual property protection through three critical boolean flags: allowDebugging, allowDownloadingSource, and includeSourceInSymbolFile.
- launch.json specifies environment connectivity, deployment targets, and schemaUpdateMode (Synchronize for safe non-destructive migration vs Recreate for rapid Docker resetting).
- ruleset.json customizes compiler code analysis rules across CodeCop, AppSourceCop, UICop, and PerTenantExtensionCop, allowing teams to elevate specific warnings to fatal compilation errors.
2.2: AL Configuration Files: app.json & launch.json Parameters
Every AL extension project relies on declarative JSON configuration files to govern compilation, deployment, debugging, intellectual property protection, and static code analysis. For the MB-820 certification, developers must possess an exhaustive understanding of app.json, launch.json, and ruleset.json, including all key properties, validation rules, security flags, and behavioral differences across cloud and on-premises environments.
1. The Extension Manifest: app.json Anatomy & Parameters
The app.json file resides at the root of every AL project and acts as the extension's manifest. It defines the extension's unique identity, minimum platform dependencies, target deployment environment, object ID allocation, intellectual property exposure policies, and localization capabilities.
{
"id": "7a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d",
"name": "Contoso Warehouse Advanced",
"publisher": "Contoso Logistics Inc.",
"version": "2.4.100.0",
"brief": "Advanced warehouse bin tracking and scanning",
"description": "Comprehensive warehouse tracking extension with 2D barcode scanning and zone optimization.",
"privacyStatement": "https://www.contoso.com/privacy",
"EULA": "https://www.contoso.com/eula",
"help": "https://www.contoso.com/help/warehouse",
"url": "https://www.contoso.com",
"contextSensitiveHelpUrl": "https://www.contoso.com/help/warehouse/{0}",
"showMyCode": false,
"runtime": "13.0",
"target": "Cloud",
"platform": "24.0.0.0",
"application": "24.0.0.0",
"idRanges": [
{
"from": 50100,
"to": 50149
}
],
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": false,
"includeSourceInSymbolFile": false
},
"features": [
"TranslationFile",
"GenerateCaptions",
"NoImplicitWith"
],
"dependencies": [
{
"id": "e8a1d2c3-b4a5-6789-0123-456789abcdef",
"name": "Contoso Core Framework",
"publisher": "Contoso Logistics Inc.",
"version": "1.2.0.0"
}
],
"internalsVisibleTo": [
{
"id": "99b1c2d3-e4f5-6789-0123-abcdef012345",
"name": "Contoso Warehouse Test Suite",
"publisher": "Contoso Logistics Inc."
}
],
"supportedCountries": [ "US", "CA", "GB" ]
}
Comprehensive Property Reference for app.json
| Property | Type | Mandatory? | Description & Exam Critical Details |
|---|---|---|---|
id | GUID | Yes | The immutable globally unique identifier of the extension. Never change the id across versions, as doing so treats the update as an entirely new extension, causing data loss. |
name | string | Yes | The unique display name of the extension. |
publisher | string | Yes | The authoring company name. The combination of id, name, and publisher defines the extension identity. |
version | string | Yes | Semantic version formatted as Major.Minor.Build.Revision (e.g., 2.4.100.0). Deploying an update requires incrementing this version. |
runtime | string | Optional | AL runtime language version (e.g., 11.0 for BC 22, 12.0 for BC 23, 13.0 for BC 24, 14.0 for BC 25). Controls available language syntax and compiler rules. |
target | enum | Optional (defaults to Cloud) | "Cloud" (default) or "OnPrem". "Cloud" enforces SaaS sandboxing rules (no .NET Interop, no direct file system access). "OnPrem" unlocks .NET interop and local OS calls. |
idRanges | array | Yes (or idRange) | Array of integer range blocks (from / to) defining permissible object IDs. Creating an object outside these ranges raises a compilation error. Use either idRange or idRanges; overlapping ranges are rejected. |
resourceExposurePolicy | object | Recommended | Replaces legacy showMyCode. Governs intellectual property protection via debugging, source downloading, and symbol generation flags. |
features | array | Optional | Compiler feature toggles. The supported values are "TranslationFile" (generates .xlf files), "GenerateCaptions", "GenerateLockedTranslations", and "NoImplicitWith" (turns off implicit with). Mandatory AppSource affixes are configured in AppSourceCop.json (mandatoryAffixes), not here. |
dependencies | array | Optional | Array of upstream extensions required for compilation and execution. |
internalsVisibleTo | array | Optional | Grants specific friend extensions (e.g., automated test apps) access to internal procedures and tables marked Access = Internal. |
Intellectual Property Protection: resourceExposurePolicy
In legacy AL, intellectual property was controlled via the coarse boolean "showMyCode": true/false. Modern AL replaces this with the granular resourceExposurePolicy object:
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": false,
"includeSourceInSymbolFile": false
}
allowDebugging(boolean):true: Allows external developers and administrators to attach the VS Code debugger to step into this extension's code during troubleshooting.false: Prevents debuggers from entering the extension's AL execution paths.
allowDownloadingSource(boolean):true: Enables administrators to download the full.apppackage containing raw source code from the Business Central web client Extension Management page.false: Blocks raw source code package extraction.
includeSourceInSymbolFile(boolean):true: Embeds the original AL source code into generated symbol packages so dependent developers can use Go to Definition (F12) to view complete method implementations.false: Emits only public method signatures, variable declarations, and object definitions, hiding internal proprietary algorithms.
2. Environment Connection & Debugger Profiles: launch.json
The launch.json file resides inside the .vscode folder. It configures deployment targets, server connection parameters, credentials, browser launching behaviors, and database schema synchronization modes.
{
"version": "0.2.0",
"configurations": [
{
"name": "Cloud Sandbox (SaaS)",
"type": "al",
"request": "launch",
"environmentType": "Sandbox",
"environmentName": "DevSandboxUS",
"tenant": "72f988bf-86f1-41af-91ab-2d7cd011db47",
"authentication": "AAD",
"schemaUpdateMode": "Synchronize",
"startupObjectId": 21,
"startupObjectType": "Page",
"breakOnError": true,
"breakOnRecordWrite": false,
"launchBrowser": true,
"enableLongRunningSqlStatements": true,
"enableSqlInformationDebugger": true
},
{
"name": "Local Docker Container",
"type": "al",
"request": "launch",
"environmentType": "OnPrem",
"server": "http://bc24dev",
"serverInstance": "BC",
"port": 7049,
"authentication": "UserPassword",
"schemaUpdateMode": "Recreate",
"startupObjectId": 22,
"startupObjectType": "Page",
"breakOnError": true,
"launchBrowser": true
}
]
}
Schema Synchronization Modes (schemaUpdateMode)
Understanding schemaUpdateMode is one of the most frequently tested concepts on the MB-820 exam:
| Mode | Behavior | Data Impact | Target Compatibility |
|---|---|---|---|
Synchronize | Non-destructive. Validates all table and field schema changes against existing database data. Fails if a change would cause data loss (e.g., shortening a Code[50] to Code[20] or dropping a field with data). | Preserves Data (Safe) | SaaS Cloud Sandboxes, Docker, On-Premises |
Recreate | Destructive. Drops all physical database tables associated with the extension and recreates them from scratch. All data in extension tables is wiped. | Destroys All Extension Data | Docker Containers & On-Premises ONLY (Strictly blocked on SaaS) |
ForceSync | Forced synchronization. Applies schema changes even if data loss occurs on altered columns, without dropping entire unaffected tables. | Potential Partial Data Loss | On-Premises & Docker ONLY (Blocked on SaaS) |
[!IMPORTANT] Attempting to publish an extension to a SaaS Cloud Sandbox with
"schemaUpdateMode": "Recreate"or"ForceSync"will fail immediately with a platform deployment error. SaaS environments permit only"Synchronize".
3. Static Code Analysis Governance: ruleset.json
Business Central includes four built-in static code analyzers to ensure code quality, platform safety, and AppSource certification compliance:
+-----------------------------------------------------------------------+
| AL Static Code Analyzers |
+-----------------------------------------------------------------------+
| | | |
v v v v
+------------+ +---------------+ +----------------+ +------------+
| CodeCop | | AppSourceCop | | PerTenantExtCop| | UICop |
| (Syntax & | | (Affixes & | | (PTE Cloud | | (Web UI & |
| Patterns)| | Signatures) | | Restrictions)| | Actions) |
+------------+ +---------------+ +----------------+ +------------+
| | | |
+------------------+----------+----------+------------------+
|
v
+---------------------------+
| ruleset.json |
| - Promote Warning->Error |
| - Suppress Legacy Rules |
+---------------------------+
CodeCop: Validates language syntax, naming conventions, formatting, and performance best practices (e.g., missing keys onSetCurrentKey).AppSourceCop: Enforces strict AppSource certification requirements: mandatory 3-character publisher affixes, backward compatibility of public procedures/fields, and properObsoleteStatelifecycle management.PerTenantExtensionCop: Checks Per-Tenant Extensions (PTE) for cloud compliance (e.g., forbidding direct file access or hardcoded company credentials).UICop: Validates user interface elements, ensuring pages include tooltips, captions, application areas, and responsive layouts.
Custom Ruleset Configuration
Teams configure custom ruleset files (referenced via "al.ruleSetPath": "./ruleset.json" in settings) to customize rule severity:
{
"name": "Contoso Enterprise Ruleset",
"description": "Enforces zero-warning policy on AppSourceCop affixes while disabling legacy casing warnings.",
"rules": [
{
"id": "AS0011",
"action": "Error",
"justification": "All public objects and fields must have an approved 3-character publisher affix to prevent collision."
},
{
"id": "AA0008",
"action": "None",
"justification": "Suppress the parenthesis-on-parameterless-calls check for legacy migration codeunits."
},
{
"id": "AW0006",
"action": "Warning",
"justification": "Warn when pages or reports omit UsageCategory/ApplicationArea and are therefore not searchable."
}
]
}
Rule Action Levels:
Error: Fails the build immediately. The extension will not compile into a.apppackage.Warning: Emits a compiler warning in the Problems pane but allows compilation to proceed.Info: Emits an informational notification.Hidden: Keeps the diagnostic active in the IDE for background tools without visual squiggles.None: Completely disables and suppresses the rule.
A commercial ISV publishes a Business Central extension to AppSource. To protect proprietary trade secrets, the ISV requires that external developers and customers cannot view internal AL procedure implementations or download the extension's raw source archive, while still allowing customers to debug and step into the code when reproducing errors. How should the ISV configure resourceExposurePolicy in app.json?
A developer working on a Per-Tenant Extension (PTE) defines the following idRanges in app.json: "idRanges": [ { "from": 50100, "to": 50149 } ] While creating a new table to track delivery vehicles, the developer declares: table 50150 "Delivery Vehicle" What occurs when compiling the project?
A developer attempts to deploy an AL extension containing breaking table schema changes to a Microsoft Business Central SaaS Cloud Sandbox using Visual Studio Code. In launch.json, the developer configures "schemaUpdateMode": "Recreate". What is the result of attempting to publish the extension with F5?
An enterprise development team requires that any missing 3-character publisher affix in an object or field name immediately halts the build process as a fatal compilation error. In the project's ruleset.json, which configuration achieves this requirement?