Monday, December 12, 2011

Resolving Compile Errors and Generating CIL is not Optional

All too often I visit clients or move in a code release to a production environment, only to find there are compile errors in the environment. This is totally unacceptable, and not just in a production environment. The existence of a compile error in a production environment is bad in itself, but it clearly shows there is an underlying problem going on in the development process.

Why is there a compile error in production, how did it get there? There are only 2 possibilities:
1) someone was WRITING/CHANGING code in production
2) there is a problem in the procedure of moving code into production

If someone was writing code in production, they should get a warning and a note in their employee file. Writing code in a production environment is one of the worst offenses a developer can make. I've known plenty of projects where developers did not have access to production at all. I absolutely love that idea because it forces proper procedures all around. I've seen consultants and developers complain about not having access to production to troubleshoot issues. If issues are severe enough they need a developer's eye and possibly debugging, it's time to take a backup of production and restore in an environment where investigation can be done (you should never have debugging on AOS enabled in production!). Contrary to some people's beliefs, making an environment copy is an easy (and relatively quick) thing to do, and it is the right thing to do. Debugging in production or manipulating data in production using the table browser or SQL without having tested this (and its impact) in a copy of production first is just as bad of an offense...

The second possible scenario is a problem with code release procedures. I've talked about this topic before in the AX 2012 code deployment article, and this is a good illustration. Deployments to production should be done in a binary, compiled form. That implies that
1) the code was compiled and checked somewhere else and moved into prod in a compiled form, so no compile errors should exist in prod after the move
2) the code that was moved into prod is the exact same as where it came from and was tested

Compile errors in prod can result from missing objects in XPOs or having to do an XPO merge while importing and making a mistake. All the more reasons to not move XPOs. To quote my deployment article: "Moving XPOs is barbaric" (it's becoming my slogan).

In either case, after moving in XPOs you should do a full compile anyway. At Streamline Systems we move layers or models, not XPOs. But even then we do a full compile after the binary code is moved in. It is an extra check that your code is ok, but more importantly it verifies that your layer works with the existing layers in the environment. What if a code change you made works by itself, but there is a customization in another layer that is now broken because of your change? You will not know until you do a full compile. And hopefully you already noticed that in a user acceptance testing environment (that has the same other layers as production) before you moved it into production. I guess layers being out-of-sync between production and a user acceptance testing environment could be considered a third reason for a production environment to have compile errors, but it comes down to a code release procedure issue as well.


Compiling brings me to my next topic. The way the X++ language works as a scripting language has gotten us spoiled over the years. The fact that X++ is a scripting language is exactly the reason why we are even talking about these issues. You can modify one object, compile it, and you're good to go. If you just broke another object by doing this code change, you won't know until run-time, or until you do a full compile of everything and find out. Think about traditional compiled development. For your code change to be incorporated, you have to recompile your whole library. If you make one code error or break something in another code file, your whole library will fail to compile and you can't run anything anymore at all until that is fixed. Besides this being good practice, it totally makes sense.
So now in AX 2012, we have the CIL generation. This generates .NET assemblies for all the X++ code. And guess what? If you have 1 compile error anywhere, the CIL generation will fail to complete. However, the .NET assemblies are used in batch jobs, services, and potentially other code being run explicitly in the CLR. (Check my previous article on X++ and CLR for details.)
As soon as the CIL generator encounters ANY compile error, it will stop going any further (just like a regular compile in C# for example). So you may have two pieces of code that are totally independent of each other. But one of the two has a compile error and CIL generation will abort for BOTH.


So here are two major conclusions I leave you with:
1) If you have ANY X++ compile errors in your system, you may end up with NO CIL code at all, even if the compile error is in a different area of code
2) Without a full CIL generation you have a CRIPPLED AX environment. Your CIL code will either be the previously compiled binaries (without your latest code change), or it won't be there at all. Batch jobs and services may not work at all, or have unexpected behavior based on the last good compile that happened.

So, resolving compile errors and having a completed full CIL generation in AX 2012 is NOT OPTIONAL. If you have compile errors in any of your environments, you should go back to your desk and start resolving them until they're fixed, right now. Failing to do so will break AX 2012, for real.

10 comments:

  1. Correct… AX2012 forces you to have code that does compile… could be great (seen in production where X++ is fine, but had to run CIL a few times, or stop users from using CLI by change the options in the ax 32bit client) else you’re going to have CIL which means no reports, aif/services and batchs.

    But this also stop the other thing which I liked about AX3,4 and 2009. which is the sharing of AOS by many devs. If one your dev's working on anything that needs CIL e.g. reports, they will not get much work done.. as the other devs are breaking X++ code, which will stop CIL coming out (plus it keeps being up and down the WCF interface). AX2012 will force one AOS per dev and daily builds. Making AX2012 more complex.

    Do we need this type of complexity for what are most the time simple business application and changes?

    ReplyDelete
    Replies
    1. I think you said it right when you said "that's what you liked about AX3-4-2009". The way X++ works as a scripting language has made it easy, and has sort of pushed us into some bad or lazy habits over the years. I think you should be fine with multiple developers though. If you run code in IL and it's not up-to-date, you will be running stale code. So unless other developers are working on the same functionality you are, that should not be an issue. The only problem arises when you yourself are creating code for IL and you can't generate it because of an error somewhere else. The one AOS per developer comes up more and more, it is an issue for TFS as well of course, so I'm not sure where this is going to go eventually. It makes sense that when you talk about a full compile of an application, as we are here, that things break when you have a lot of people working on the same code at the same time. I'm not sure that as a VAR, how we would support a model with an AOS for each developer. On a client site, it's feasible. For consultants, not so much.

      As you pointed out, AX 2012 is more complex, and it's not just the development tools. Yes, we loose some flexibility, but for the most part it's forcing us to follow good development practices. And in the end, we're still talking about a business critical application. Microsoft is no longer aiming at 10-user implementations with this release. They are going after the big fish.

      Delete
  2. Hey Joris,

    Thanks for the valuable information here. We have setup a new AX 2012 environment for one of our client and having the stack trace error accross the different functionalities in System. We suspect the .NET BI classes has not been compiled correctly as the CIL compilation coming up with 15 warnings. All warnings are BI\Classes\BIAnalysisServicesProjectController related. Any help on this would be much appreciated.

    Thanks,
    Pankaj

    ReplyDelete
    Replies
    1. If all you received are compiler warnings you should be ok as far the CIL finishing correctly. What is the stack trace you are receiving?

      Delete
  3. Hi Joris,

    Is it normal to "live" with compile errors from objects that belong to other localizations? In my case, I'm getting compile errors from objects for Italy and Spain, and I'm in Mexico. Is there something to do or just live with them?

    Thanks,

    Ricardo

    ReplyDelete
    Replies
    1. There shouldn't be any compile errors, period. If you have issues with localizations, they must not be standard, maybe customized, or perhaps the wrong version compared to your base AX version.

      Delete
  4. Hi Can you tell me a way to generate CIL in AX 2009 I am unable to find any option. I'll really appreciate your help

    ReplyDelete
    Replies
    1. CIL is a new feature in AX 2012. Which is why I wanted to point things out in this article; many people upgrading from AX 2009 don't realize that CIL is crucial.
      But not an issue for you.

      Delete
    2. I am facing the same problem, error occurred during the Compilation to .Net CIL Generation, I did the same what ever you mention,
      I went to the location of XPPIL directory and removed all the assembly from there, after that i synchronize the database and the full compilation and next the CIL generation, but no improvement.
      I want to dictate my scenario over here.
      My Database is 2012 standard and located on this (10.6.123.50)
      and AX2012 R3 is on different IP (10.6.123.51).
      Installation done successfully as well as Application Compile without any error.
      the next step when compile with CIL Generation, error occurred "The CIL generator found errors and could not save the new assembly”.
      what should be possible error in this environment.
      For your clarification,
      User is Member of Domain Admin and Admin of local system.
      Thanking you

      Delete
  5. I am facing the same problem, error occurred during the Compilation to .Net CIL Generation, I did the same what ever you mention,
    I went to the location of XPPIL directory and removed all the assembly from there, after that i synchronize the database and the full compilation and next the CIL generation, but no improvement.
    I want to dictate my scenario over here.
    My Database is 2012 standard and located on this (10.6.123.50)
    and AX2012 R3 is on different IP (10.6.123.51).
    Installation done successfully as well as Application Compile without any error.
    the next step when compile with CIL Generation, error occurred "The CIL generator found errors and could not save the new assembly”.
    what should be possible error in this environment.
    For your clarification,
    User is Member of Domain Admin and Admin of local system.
    Thanking you

    ReplyDelete