Dynamics ax 2012 : AxBuild.exe xppcompileall stuck on 3 asterisks

Recently with one of the customer i faced this issue, Each time the compile starts, it just shows the AxBuild prompt with 3 asterisks and the window closes after about 15-20 minutes (without actually doing anything).

Event i have run the command as Admin but nothing worked and faced same problem

axbuild.exe  xppcompileall  /s=01 /altbin=”C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin”

After enough research i came to know that this is possible in two scenarios. The first one is the permissions, ensure the user running axbuild.exe has the same permissions as the AOS Service account and account should have enough access on AX database also. For me this was the problem the account through which i am login to system does not have enough permission to AX database.

AxBuild.exe must be run by an account that has no less security authority than the account that runs the permanent AOS has.

Source: https://msdn.microsoft.com/en-us/library/dn528954.aspx

The second time, it happened when the SQL Server had no more RAM resources available. Then fix would be to clear memory for SQL service.

Thanks for reading

Happy daxing 🙂

Amir

 

Dynamics ax 2012 Id Conflicts

Hi Guys,

Recently i was experiencing the Upgrade and i have faced Id conflicts issue, This blog is about what i have experience and how i am able to rectify and identify the problem.

This content is re-blog of following two posts, through that i got the required info and fixed my issue.

http://dev.goshoom.net/en/2011/11/id-change/

https://yetanotherdynamicsaxblog.wordpress.com/category/sql/

So what is Conflicts ?

If a table ID or field ID is changed in Dynamics AX, data are lost during synchronization, because the table with the old ID (and containing data) is dropped at the beginning and then a new table is created with the same structure but a different ID. The same is valid analogically for table fields.

The data loss can be prevented in several ways (e.g. by data export and re-import), but one solution is really simple and painless. Realize how the situation looks in AX after the ID change (e.g. after installation of a layer with different IDs) but before the database synchronization:

Where Ids are stored in AX ?

You can identify all changed IDs by comparing values in AOT with values in SqlDictionary. And the update of SqlDictionary to the new ID can prevent the regeneration of database objects during synchronization.

ReleaseUpdateDB::changeTableId method is used to updated the SQLDictionary table it takes new and old table id and table name to update the record.

 //Updates table ID in SqlDictionary  
       if (ReleaseUpdateDB::changeTableId(  
         sqlDictionaryTable.tabId,  
         dictTable.id(),  
         dictTable.name()))  
       {  
         info(strFmt("Table ID changed (%1 -> %2)", sqlDictionaryTable.tabId, dictTable.id()));  
       }  

Sometime there is also the need of updating the table id and reflect in the metadata.

There is a Table with name “ModelElement” in AX model database. In this table we have few important fields as, it is important for us to understand these fields.

1. ElementType : this field contains type  ID of data object like for table fields its value will be 42 and for tables it will be 44.

2. AxId : this field contains actual object ID value which create conflicts among environments. We have to change this field value, e-g for AccountNum field of CustTable it could be as 1.

3. ParentId : this field contains parent object ID, like ID of the table, whose field we are looking at, e-g for AccountNum field of CustTable it could be as 77, which is table ID for CustTable.

I have build this query to check the table ids using sql.

 // this query can be used to read the current table id from model db  
 SELECT ELEMENTHANDLE, ROOTHANDLE, NAME, AXID, ORIGIN FROM MODELELEMENT   
 JOIN ELEMENTTYPES ON MODELELEMENT.ELEMENTTYPE = ELEMENTTYPES.ELEMENTTYPE  
 WHERE NAME IN ('legCustTableLegacy', 'legACCCreditLimitLevelLine', 'legAccountsParameterSetup', 'legAXEnums') AND ELEMENTTYPENAME IN ('TABLE')  
 
//This query can update the table id and reflect in meta data.  
 Update M  
 SET m.AxId = 105871  
 FROM MODELELEMENT as M  
 JOIN ELEMENTTYPES ON M.ELEMENTTYPE = ELEMENTTYPES.ELEMENTTYPE  
 WHERE NAME IN ('legACCCreditLimitLevelLine') AND ELEMENTTYPENAME IN ('TABLE')  

Thanks for reading this

Happy Daxing 🙂

Good practices with Code Deployment Dynamics ax 2012

This is not my original blog, but i have found very good comment from Tommy Skaue on community related code deployment and i really like to make it part of my blog so all should be aware of the best practices. This is about the modelstore installation to different environment and practices we need to following during code deployments.

1. Production

Always move changes to production from a Staging/Test/User Acceptance Testing environment. Move the entire ModelStore, precompiled X++ and CIL without any errors. Install it first to a temporary database schema (http://yetanotherdynamicsaxblog.blogspot.no/2013/02/deploy-modelstore-with-less-downtime.html), then take all the PROD AOSes down, then apply it, then start 1 AOS and run a data dictionary synchronize  Then start any other AOSes pointing at PROD.

2. User Acceptance Test (UAT)

Given a single test environment, you will install changes to this environment using models. There are scenarios where XPO is ok, which I will comment down below.
Given a separate build environment for test, you will move code to UAT using modelstore from build to UAT. In a perfect world, you will never install a model in UAT that has compile errors or dependency issues. Remember that whenever you install a model and need to run compile + synchronize  this process will take hours. Schedule it outside testing hours or consider setup a build environment.

Code is moved from here to Production using modelstore. Data is updated from Production to UAT. Environment IDs are shared, except from any new IDs introduced in UAT waiting to be shipped to Production. 🙂

3. Development

Some customers will accept having a customer specific developer environment, which allows us to develop customer specific customization without interfering with test. This is highly recommended. Here you will install updated models, your own and third party models, update customer specific models, merge code and compile. You can move code into this environtment using both models and XPO.

You may schedule a restaging of the data and the code in Development, meaning you backup the UAT database(s) and restore them over Development. Remember to backup the models in Development (http://yetanotherdynamicsaxblog.blogspot.no/2012/09/using-powershell-to-backup-your-ax-2012.html), in case someone forgot they had super important code in Development that wasn’t already shipped to UAT.

Over time the IDs in Development will stray away from Prod and UAT, so never move a modelstore from Development upwards without knowing what you are doing.

Models vs XPO

There are scenarios where XPO is an easy and convenient way to move code from A to B.
One clue is to know when introducing changes causes new IDs to be created. At this point, you need to know if this newly created ID will cause your UAT/Test and Prod to have different ID for the same element. If that happens, you’ve lost control and you need to restate UAT/Test again completely from Prod.
Another clue is when your XPO contains an element that contains changes bound to multiple AX models. Remember the XPO does not contain information of what change is bound to what model, so whatever you import using XPO will bind that change to the model you are currently working in. This may cause changes to be bound to a wrong model cause all sorts of havoc and issues later down the road.

So actually, you can move small changes to existing methods using XPO without introducing IDs if those changes all reside in the same model you exported the XPO from, if you catch my drift. You can also move SSRS reports with XPO safely. There are many scenarios supporting the use of XPOs, but you need to leave the mindset from pre-AX2012 where anything could be moved using XPO. Either you figure out when XPO can safely be used, or you refrain from using it altogether (like Joris recommends, sort of). 😉

Final note

Moving a precompiled modelstore is only good when the source and targets share the same environment IDs. Production and UAT/Test should use the same IDs, allowing you to have things properly tested before putting it in production, PLUS allowing you to prepare a precompiled ready to launch modelstore having perfectly valid element IDs.

When installing models you need to compile + synchronize. This is a time consuming process and more often you need to keep users out during.

When moving changes using XPO, you need to know how and why it will be ok to move changes using XPO. If you don’t know the how and why, then don’t use XPOs at all.

Thanks Guys

Happy Daxing 🙂

Reading Infologs and Inserting new line for email body Dynamics ax 2012

I have designed a feature where i need to send the executions logs of Batch on its completion via email, That part is done perfectly fine and emails starts coming, I have read the infologs and concatenate the two strings so i can make one big string of multiple infologs, i was using \n between two strings but when i call the email sending code and pass the string; The new lines are not coming to email. The format for sending email was HTML.

i came to know that for HTML format. White spaces such as line-breaks are suppressed in HTML; and we have to use tags like <p> or <br />.

I have also pasted sample code on how i am reading the infologs and added <br/> tag for line break.


 private str 5000 readInfoLog()  
 {  
   SysInfologEnumerator enumerator;  
   SysInfologMessageStruct msgStruct;  
   Exception exception;  
   str 5000 Message;  
   enumerator = SysInfologEnumerator::newData(infolog.copy(1,infologLine()));  
   while (enumerator.moveNext())  
   {  
   msgStruct = new SysInfologMessageStruct(enumerator.currentMessage());  
   exception = enumerator.currentException();  
   message = message + strFmt("Type: %1; Message: %2",  
   exception,  
   msgStruct.message()) + '<br /> ';  
   }  
   return Message;  
 }  

Thanks
Happy Daxing