X++ compilation

When I recently read the post Resolving Compile Errors and Generating CIL is not Optional by Joris de Gruyter, I immediatelly recalled several problems I keep meeting in companies that develop and maintain Dynamics AX-based solutions. I’m going to speak only about the “normal” compilation to p-code, not to CIL.

From a fault prevention point of view, compilation has two important reasons:

  1. It detects compilation errors
  2. It updates bytecode, so the correctly written code is also run correctly.

1. Early identification of compilation errors

Most companies (not all!) realize that applications must be at least compilable, if nothing else. Despite that they run compilations rarely – they are either not aware of consequences or they think it’s too time-wasting.

Therefore many projects count with a complete compilation, but not before deployment, very often in the production environment only. The consequence is late error detection and failed deployment of the application.

Such a (failing) scenario may look like the following:

  1. A developer make a compilation error outside his project. (For example he adds a mandatory parameter to a method and doesn’t update a method call in another component. By the way, that’s often impact of outdated cross references.)
  2. His project is compilable, it’s moved in .xpo to a test environment etc. – Nobody is aware of any error.
  3. The full layer from the test environment is deployed to the production environment, but compilation fails.
  4. The deployment must be cancelled and people have to start looking for the problem.

The error could have been found during development – but now, several months often went by and developers must familiarize themselves with the code again. Changes in code also require repeated testing, the deployment must be done again (including a service window planning etc.), in short the cost of such an error is quite high. And that call could have been prevented if anybody compiles the application earlier.

2. Bytecode update

From a technical perspective the purpose of compilation is to translate human-readable source code to a form better understandable by computers. But under certain circumstances Dynamics AX gets into the situation when the source code is all right but it’s not correctly compiled – typical symptoms are mysterious runtime errors, nevertheless the consequences are unpredictable in general.

A typical example is the runtime error reporting wrong types in a variable assignment, although the assignment is obviously correct (e.g. assigning true to a boolean variable). That’s the sign that the runtime environment runs something else than what is stated in the source code.

I don’t know exactly under what circumstances can this error occur (that would rather be a question for Microsoft) but I have one situation reliably tested – problems often occur when member variables in a class change, but other classes in the inheritance hierarchy are not recompiled. Then it often happens that AX tries to assign values to wrong member variables.

People are usually not aware of the cause of these troubles and even after getting the explanation they try to avoid compilation as they can. The typical reaction is to order developers to compile all classes using Compile forward. One problem is the observation of this order, but especially it still doesn’t solve the conflict between the modified class and it’s ancestors. Sure, it would be possible to take the modified classes, identify the appropriate parent of each of them and run Compile forward from it, but compilation of the application is simpler (and it has also other advantages).

A horror story

Although almost every team has some problems regarding compilations, some cases stand out. I even know one Gold Partner that doesn’t compile applications at all (I know that one of their customers has forty compilation errors in the production environment), problems with incorrectly compiled code (the same as I describe in 2. Bytecode update) occur constantly and each of them is solved as a separate support call. Because this company manages to get some money from customers even for these cases, they may consider it as a more profitable strategy.

I really hope that this is an exception.

Solution

I hope we all agree that compilation is important, but now how to run it and how often?

If you have just few environments, even manual runs can be satisfactory. At the close of the day you can simply start the compilation of the whole AOT and look at results in the morning. It can’t be more simple. The argument, that the compilation is very time-consuming, doesn’t play a role – it has all night when the application is not used anyway.

If you have more environments or if you want to start the compilation late at night, it’s much better to automate it. You don’t have to use PowerShell scripts from this blog, you can simply create a scheduled task in Windows and run AX with -SysStatupCmd=CompileAll parameter. But don’t forget to look at results sometimes – otherwise you didn’t solve the problem about compilation error detection.

Once you have an automated process, runs doesn’t cost you anything and therefore there is no problem to compile frequently. I personally promote running compilations every night and full update of cross references every weekend.

One Comment

  1. Thanks for the shout-out.
    As for your Gold Partner reference, I’m afraid it’s not the exception. We have been called in quite a lot of “recovery” situations (fixing bad or failed implementations), and trust me the level of amateurism in this business is staggering sometimes. I’m even dealing with an ISV that has sold us a vertical, which has compile errors as well as object ID issues (their BUS layer has objects that have USR and VAR range object IDs). And that’s just the technical aspect of their vertical.

    I’m hopeful this will change as the product gets bigger and more complex, and everyone is forced to do things better (you just have to – things will break BADLY).

    As for the compiles, we use TFS branches and builds to move code, so we catch these types of compile errors as soon as development is done and we move code to the client’s system. However, we are actually currently setting up a nightly build (using TFS) that does a full compile on the development environment to, like you said, catch it even earlier. We are also adding some extra code in there (eg checking if there are any customized objects that haven’t been added to version control!). TFS can be set to only do that nightly build when any code has been modified, to avoid needless builds.

Comments are closed.