Microsoft is continuing to modernize the X++ language in Dynamics 365 Finance & Operations by removing legacy concepts that are no longer relevant to the current platform architecture.
One such change affects the client and server keywords used in X++ method declarations.
These keywords have been obsolete from a runtime perspective for many years, but they have remained in existing X++ code. Microsoft has now started the process of removing them from the language.
If you maintain an older Dynamics AX or D365 F&O codebase, this is something you should check before moving your development environment to the newer platform versions.
What Is Changing?
Historically, X++ developers could use client and server modifiers to specify where a method should execute.
For example:
public client static void updateCustomer(){// Method logic}
or:
public server void processOrder(){// Method logic}
With the modern Dynamics 365 Finance & Operations architecture, these modifiers no longer control the execution tier of the method.
Microsoft explains that X++ methods currently execute on the server tier, making the old modifiers unnecessary. Starting with platform update 10.0.48, the compiler began reporting these keywords as warnings and Microsoft has instructed developers to remove them from existing code and avoid using them in new development.
The next important step is 10.0.50, where their use results in compilation errors.
The transition looks like this:
| Platform version | Behavior |
|---|---|
| 10.0.48 | client and server generate compiler warnings |
| 10.0.50 | Their use causes compiler errors |
| Future versions | The keywords are expected to be removed completely from the X++ grammar |
This makes the change particularly important for teams maintaining large customizations or legacy code.
Why Were These Keywords Deprecated?
The client and server modifiers made sense in the older AX architecture, where developers needed to distinguish between client-side and server-side execution.
The architecture of Dynamics 365 Finance & Operations is different.
As Microsoft notes, these keywords no longer determine where the method executes. Consequently, keeping them in the language adds legacy syntax without providing meaningful runtime behavior.
For example, this:
public client static void updateCustomer(){// Update customer}
can simply become:
public static void updateCustomer(){// Update customer}
The client keyword is removed, but the method itself remains unchanged.
Similarly:
protected server void calculateAmount(){// Calculate amount}
becomes:
protected void calculateAmount(){// Calculate amount}
There is no need to redesign the method merely because the obsolete modifier is being removed.
Does Removing client or server Change the Method's Behavior?
In general, no.
The important point is that these modifiers are no longer responsible for determining execution location in the current D365 F&O architecture.
Therefore, removing the modifier is primarily a source-code cleanup and compiler-compatibility change, rather than a functional change to the business logic.
For example:
Before
public client static void createCustomer(){// Business logic}
After
public static void createCustomer(){// Business logic}
The method's access modifier, return type, name, parameters, and implementation remain intact.
Only the obsolete keyword is removed.
How to Find These Keywords in an Existing Project
If you are working with a solution that has been upgraded from AX 2012 or an older D365 F&O implementation, it is worth scanning the X++ codebase.
A basic search for:
clientserver
can help identify potential occurrences.
However, don't blindly remove every occurrence.
The words may appear in:
Comments
String literals
Variable names
Documentation
Other code where they are not being used as method modifiers
What you are specifically looking for is a method declaration such as:
public client static void methodName()
or:
protected server void methodName()
The relevant change is to remove only the obsolete modifier.
Recommended Cleanup Process
Before upgrading your development environment to a platform version where these keywords produce compilation errors, I recommend the following approach.
1. Search the X++ codebase
Search your custom models and projects for:
clientserver
2. Review the results
Do not perform a simple find-and-replace.
Verify that each occurrence is actually being used as an X++ method modifier.
3. Remove the obsolete modifiers
For example:
public client static void process()
becomes:
public static void process()
And:
private server void calculate()
becomes:
private void calculate()
4. Compile the affected projects
After making the changes, perform a build and check for any remaining compiler warnings or errors.
5. Run your normal validation
Although this particular change should not alter business logic, your normal build and regression-testing process should still be followed.
Microsoft's guidance on D365 F&O updates highlights that some platform changes can introduce design-time compilation issues even when runtime/binary compatibility is maintained.
What About New X++ Development?
For new development, there is no reason to add these modifiers.
Avoid writing:
public client static void myMethod()
or:
public server void myMethod()
Instead, use the normal X++ method declaration:
public static void myMethod()
or:
public void myMethod()
This keeps your code aligned with the current X++ language direction and avoids unnecessary compiler warnings or future compatibility issues.
A Small Change That Can Affect Large Codebases
The actual code change is very small.
The challenge is more likely to be the size of the codebase.
Large D365 F&O implementations can contain:
Years of custom X++ development
AX 2012 migrated code
ISV customizations
Extensions
Legacy integrations
Utility classes
Old framework customizations
A project may therefore contain these modifiers in places that developers no longer actively maintain.
That is why it is better to identify and clean them up proactively instead of waiting for the platform upgrade to turn them into compilation errors.
Important Point for AX 2012 Developers
Developers coming from AX 2012 may remember that client and server were meaningful concepts when deciding where X++ code executed.
That historical behavior is exactly why these keywords can still be found in older codebases.
However, developers should not assume that the presence of these keywords today means the method is being forced onto a particular tier.
Microsoft's current documentation explicitly states that the keywords were useful in AX 2012, but in the current architecture they no longer make sense because methods execute on the server tier.
Quick Example
Legacy Code
public client static void processSalesOrder(SalesId _salesId){// Process sales order}
Updated Code
public static void processSalesOrder(SalesId _salesId){// Process sales order}
Another example:
Legacy Code
protected server Amount calculateTotal(){// Calculate total}
Updated Code
protected Amount calculateTotal(){// Calculate total}
In both cases, the business logic remains untouched.
Final Thoughts
The deprecation of client and server is a relatively small X++ language change, but it is worth addressing early if you maintain a large or legacy D365 F&O codebase.
The key takeaway is simple:
client and server should no longer be used as X++ method modifiers.
If your existing code still contains them, remove the obsolete modifiers, compile the affected projects, and address any resulting compiler diagnostics before moving to the affected platform version.
For developers maintaining older AX/D365 F&O implementations, this is also a good opportunity to clean up legacy X++ syntax and keep customizations aligned with the current platform architecture.
No comments:
Post a Comment