mfp's two cents

...on Dynamics AX Development!
  • mfp's two cents

    X++ Debugging Tips and Tricks #2 – xSession::xppCallStack()

    • 2 Comments

    X   Debugging banner 2

    In the first trick we saw how to set a breakpoint in the add method on the info class. This enables us to get the context of a single error.   But sometimes error messages come in hoards and stepping through each of them is not practical. Suppose you have hundreds or even thousands of errors occurring, and you want to trace where they are coming from. This trick shows you how.

    This trick requires code instrumentation – I will strongly discourage using this trick on a production system. Only use this trick in a test or development sandbox!        
           
    The system APIs available in Dynamics AX are fantastic. There is hidden gem of an API that gives access to the current X++ call stack in the form of a container. This makes it relatively simple to include the call stack in the error messages shown in the Infolog. Just insert this line of X++ code in the add method in the info class just after the variable declaration section:

    _txt += con2Str(xSession::xppCallStack()); 

    Now run the scenario, and inspect the Infolog. It will include the call stack for each message, and will look something like this:

    Infolog-debuggingtipsntricks

    With this information it is much easier to browse through the many messages in the Infolog and find variations in the call stacks.

    This post is provided AS-IS, and confers no rights or warranties.

  • mfp's two cents

    X++ Debugging Tips and Tricks

    • 3 Comments

    X   Debugging - Full 2

    I hate debugging - I would much rather write code or watch tests execute! Debugging is a waste of time, and often follows an unpredictable path.

    Any developer knows the situation: A bug is discovered, and the cause must be found. Most developers have these war stories on how they fought with a bug. The battle swung back and forth. Theories were tested and discarded, instrumentation was built, log files were examined, Murphy visited and, coffee was spilled. When the stories are told, they typically have a happy ending, so eventually the Eureka-moment occurred and the cause was found. And a debugging lesson was learned.

    One of my toughest debugging session spanned almost 2 weeks. My code was complete and ready for check-in. I had worked on it for about 2 months in a private branch. Before reverse integrating into the main branch I ran all unit tests. A successful run takes about 12 hours. In my case the execution crashed after about 10 hours. I tried to run the single test case that crashed in isolation. It passed. I tried again with the full automation. It still crashed. I then tried disabling the crashing test, just to realize 10 hours later, that now a different test crashed. I then tried running with a debug version of AX32, so I could debug the crash. But the debug build is much slower, so it would take ages before the crash happened. So I needed to isolate the crash in a simpler repro. I tried changing the order of tests, and with every change I made the crash moved somewhere else. I then began trawling the system logs for information about the crash. This lead me to think about memory – perhaps something was leaking memory. I instrumented the test automation, so it would dump the current memory footprint every 10 seconds to a log file. And yes – memory consumption climbed until the crash occurred. But hey; I’m just writing X++ code – what can I possibly do that causes memory to leak? Driving home one day I got the idea that perhaps it was not my code, but the X++ runtime. After all; I was using some of the not-yet-released-at-this-point X++ features pretty heavily (attributes and events). So I wrote a small job, that exercised these areas heavily, and I saw memory climbing slowly but steadily until the crash. Now with a simple repro in hand, it was not hard to solve the issue – but I did require help from my friends in the X++ team. Two weeks had passed before I was ready to submit, my code was exactly the same, and now all test passed.

    This X++ debugging series of posts is dedicated to share X++ debugging tips and tricks. Having a toolbox full of different ways to attack bugs is required to be a productive developer. I’m going to share some of my tricks. If you have tricks of your own, please write a comment, and I will include them in the series. The ultimate goal is that we all efficiently find and solve X++ bugs.


    Trick #1 – Breakpoint in Info.add()

    Trick #2 – xSession::xppCallStack()

    Trick #3 – Conditional breakpoints

    Trick #4 – Reading uncommitted data

    Trick #5 – To be announced


  • mfp's two cents

    X++ Debugging Tips and Tricks #1 – Breakpoint in Info.add()

    • 2 Comments

    This trick is probably the first every X++ developer learns, so it deserves to be the first on the list of X++ Debugging Tips and Tricks.

    Suppose an X++ exception occurs and you want to know why. The error is written to the Infolog. Double-clicking the line in the Infolog window will bring you to the line that threw the exception. Sometimes it is trivial to see the cause just by looking at the code. Other times it is not, and you will need the entire context including the call stack and variables to figure out what the cause is.

    Set a breakpoint in the add method on the Info class – and rerun the scenario. When the exception is thrown your breakpoint is hit, and you can perform the autopsy.

    Debug-trick-1_thumb1

    This post is provided AS-IS, and confers no rights or warranties.

  • mfp's two cents

    Item tracing functionality in Microsoft Dynamics AX 2012 R2 CU6

    • 0 Comments

    I recently joined the A SCM Inventory team at MDCC – so let me direct your attention to a significant improvement in CU6 in the Inventory area.

    Please follow this link:

    http://blogs.msdn.com/b/dynamicsaxscm/archive/2013/08/13/new-item-tracing-functionality-in-microsoft-dynamics-ax-r2-cu6.aspx

  • mfp's two cents

    Microsoft Dynamics Lifecycle Services is Live

    • 1 Comments

    lcs2

    Microsoft Dynamics Lifecycle Services are designed to manage and optimize customer implementations – powered by Azure. The customer creates project workspaces for implementation, upgrade and maintenance activities, and will invite implementation experts from partner organizations and Microsoft into these workspaces for the execution of related activities. Partners will be able to create projects for learning and presales purposes. This enables partners to build out expertise around Lifecycle Services, and demonstrate this in sales cycles.

    lcs

    Take it for a test drive @  https://lifecycleservices.dynamics.com.

     

     

    COLLABORATION WORKSPACE

    • Customer-managed collaboration workspace
    • Cloud-based, secure environment
    • Project management using SureStep or other methodologies
    • Project-specific dashboard
    • Tools & data that connect multiple lifecycle phases to enable better decision making by key stakeholders

    Business process modeler

    • Aligns industry processes (APQC) with process maps for Microsoft Dynamics AX.
    • Create cross-functional flowcharts based on rich metadata.
    • Map processes & perform fit-gap analysis.
    • Integration between BPM & RapidStart.
    • Quickly generate documents and flowcharts using TaskRecorder (KB#2863182).

    CODE & UPGRADE ANALYSIS

    • Leverages a cloud-based rule engine to analyze code and identify potential best practice, performance and upgradeability issues.
    • Generates actionable reports in Excel & HTML that can be imported into MorphX IDE as actionable to-do’s for developers.

    License sizing estimator

    • Estimate how many licenses you need (CAL)
    • Model the effect of custom roles on license needs.
    • Get automatic CAL-level estimates

    USAGE PROFILER

    • Model user & batch AX loads.
    • See graphic representation of load volumes.
    • Identify a starting point for infrastructure sizing.

    Issue search

    • Search a repository of reported, in-progress & fixed issues.          
    • Identify specific code objects & lines of code affected by hotfixes.
    • Get notifications for issue state changes, and new fixes for AX functional areas.

    DIAGNOSTICS

    • Automate & monitor health checks for AX ecosystem.
    • Collect data from AX environments.
    • Evaluate data against pre-defined rules & health checks.
    • Generate reports to provide monitoring & actionable corrective action summaries.

  • mfp's two cents

    Debug::Assert in X++

    • 3 Comments

    Update 4th of August 2014: Clarification of the AX runtime behavior when non-developers hit an assert statement.



      defect free software

    “In computer programming, an assertion is a predicate (a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place.”    

    http://en.wikipedia.org/wiki/Assertion_(computing)

    What would you rather have: A piece of source code with or without assertions? I’d definitely prefer source code with assertions – it makes the code easier to read, debug and troubleshoot.

    My recommendation is to use assertions in X++ when all of the following are true:

    1. The condition can never be false if the code is correct, and
    2. The condition is not so trivial it obviously be always true, and
    3. The condition is in some sense internal to the component, and
    4. The condition can be verified without any method calls.

     

    1. The condition can never be false if the code is correct

    Assertions and error handling are two different things.

    • Assertions should be used to document logically impossible situations in a correctly implemented program. If the impossible occur, then something is wrong – a programming error has been discovered.
    • Error handling – as the name implies – is the implementation of what should happen when an error occurs. Error handling are valid code paths that determines how the software reacts to various erroneous conditions, like incorrect data entered by the user, to system error conditions like out-of-memory.


    In a nutshell, it should be possible to write unit test for error handling – but not for assertions.

    2. The condition is not so trivial it obviously be always true

    Assert statements takes time to write and read – and if the condition they are asserting is obviously always true, then the assertion is pure clutter – and we are better off without it.

    3. The condition is in some sense internal to the component

    A failing assertion is an indication of a problem with the implementation. Something within the component – regardless of input from the outside world – is broken and needs fixing. Typically, I’d use assertions for input validation in private methods, and exceptions in public methods. Conversely, you don’t want consumers of your component to be hit by assertions – regardless of how they use your component.

    4. The condition can be verified without any method calls.

    Assert statements in X++ are a little special, as the X++ compiler always includes assert statements. In other languages (like C#) you can have multiple compiler targets – and typically the release build would not include the assert statements. In AX when a non-developer is hitting an assert statement, then the runtime will suppress eventual errors. I.e. in a production system assert statements have no functional impact.

    Given assert statements in X++ are always evaluated, and thus degrades performance, they should be used with a bit of caution. If the condition can be verified with minimal overhead – for example that a variable has a certain value – then there is no problem. However; if the assertion requires execution of complex logic, RPC or SQL calls then it should be avoided, due to the performance impact. In cases where the performance impact is significant, but you don’t want to compromise on assertions, the assertions can be wrapped inside a call to Debug::debugMode().

    “without any method calls” is just a guiding principles. Sometimes it makes sense to factor the condition into a Boolean method – for reuse or for clarity – here I would not object.

    Examples

    Here is an example of good use of assertion in X++:

    private void markDetailRecordAsEdited(
    RecId _journalControlDetailId,
    RecId _draftConstraintTreeId) { Debug::assert(_journalControlDetailId != 0); Debug::assert(_draftConstraintTreeId != 0); if (! modifiedDetailRecords.exists(_journalControlDetailId)) { modifiedDetailRecords.insert(
    _journalControlDetailId,
    _draftConstraintTreeId); } }

     

    Here is another example where Debug::debugMode() is used:

    private void render()
    {
        ...
        
        if (Debug::debugMode())
        {
            Debug::assert(this.hierarchyCount() > 0);
            Debug::assert(segments != null);
            Debug::assert(totalSegmentCount > 0);
        }
    
        ...
    }

    Closing remarks

    I once saw a t-shirt with this print on the front: “If debugging is the process of removing bugs, then programming must be the process of putting them in”.  I wish the back had read: “Programming with assertions is one way to keep bugs out.”

  • mfp's two cents

    Microsoft Dynamics ERP software now available on the Azure cloud

    • 0 Comments

    Cloud

    Read more here.

  • mfp's two cents

    SysExtension Framework – to the rescue

    • 5 Comments

    There is a coding pattern that has been proliferating the X++ code base for years. It is not an X++ best practices – nor is it object oriented; yet it is used quite heavily (unfortunately). Consider a simple class hierarchy with an abstract base class and 3 derived classes. A typical implementation of a factory would be a static method on the base class, like this: (Please ignore the type of the parameter – it could  be anything, I choose str for simplicity)

    image

    Now; the problems with this approach are many.

    • First of all the base class has references to the sub classes. Why is that a problem? Consider the base class is a framework class – is it a good idea for framework classes to have references to consumer classes of the framework? Of course not – we don’t like that coupling.
    • Secondarily; the 3 subclasses are all referenced by the same method. Any new sub class would require an update to the factory. This turns the method into a congestion point, and it creates a coupling between sub-classes.

    The coupling between the 4 classes spells trouble. If you try to modularize an application written like this, you will quickly realize that the pattern above is bad. You cannot have references from lower-level models (aka. assemblies/modules) to higher-level models. Yet; having a single factory method is valuable and a good practice.

    SysExtension Framework to the rescue.

    Consider you decorate the subclasses with an attribute, like depicted here:

    image

    Then you can rewrite the factory method to this:

    image

    The extension framework returns an instance of the right subclass automatically. It uses the attribute to determine which subclass instance to create. Quite simple – extraordinary powerful!

    Now notice:

    • Truly decoupled! New subclasses can be added without any changes to the base class.
    • Less code is required! In the example here the delta is not significant – but sometimes you have switch statements spanning hundreds of lines.
    • No change in the public API! The contract stays the same – this is an easy and low risk refactoring.

    A few words of caution: There is a small performance impact on cold systems when using the SysExtension framework. In most cases you will not notice it; however – for performance critical paths, you should measure the impact of this change before going for it.

    To learn more about the SysExtension framework see here.

  • mfp's two cents

    An amazing AX day in Moscow

    • 0 Comments

    Navicon’s AX Fair in Moscow was a big success. Around 150 peopled gather to learn about Microsoft Dynamics AX 2012. There were a few keynotes followed by two breakout tracks, hands-on labs to allow everyone to interact with AX 2012. Also every attendee got a free copy of the Russian version of Inside Dynamics AX 2012. The book has been translated by Navicon – the host of the conference.

    The Fair was dressed in traditional Russian style and colors, including a guy playing the mandolin (I think) most of the day.
    WP_20130607_022
    WP_20130607_003 The first keynote was by Алёна Геклер from Microsoft Russia – I ‘m sorry to say that I missed some of the details, as both the slide deck and the talk was in Russian.

    I followed next, speaking about developing large scale software, and how a MS-Press book is written.

    The next keynote was by Vadim Korepin – who among other things gave Navicon’s expectations to future AX versions.

    Vadim is also my host for the conference, and he has been the main translator of the Russian version of Inside Dynamics AX 2012. He has done a great job, and I’m sure he will be tired tonight.

    WP_20130607_010
    WP_20130607_011 The final keynote was by Oleg Ognev, Director of IT at IZOVOL. He spoke about Izovol’s AX implementation. Izovol is the first live Russian customer running Microsoft Dynamics AX 2012. The talk also covered why AX was chosen over SAP and Oracle - again the talk was in Russian – but my interpretation was that AX is simply much better.

    During lunch there was a book signing session. The excitement around the book truly amazed me – I stopped counting how many hands I’ve shaken and how many dedications I’ve written.

    Being a bit challenged by the language, I selected to attend the few English sessions. I saw Keith Thaulow, EMEA Sales Director, Demand Solutions speaking about the importance of good Forecasts for Sales and Production. The forecasting solution from Demand Solutions can free up cash tied up in Inventory – you can expect to reduce the inventory levels by at least 10%; and whats equally amazing is that the vast majority of companies installing Demand Solutions’ AX Forecasting solution is able to have it fully implemented within the first 6 months. WP_20130607_017
      

    Tonight I’m having a tradition Russian/Ukrainian dinner with developers from the Russian community.

    Спасибо Москва

  • mfp's two cents

    Navicon AX Fair in Moscow

    • 0 Comments

    Navicon

     

    I’ve been invited to speak at the Navicon AX Fair in Moscow on June 7th 2013. I’m looking forward to my first visit to Russia – and meeting customers and partners, who are as excited about AX 2012 as I am.

    If you are in the neighborhood and want to join the Fair, make sure to sign-up here.

Page 3 of 20 (191 items) 12345»

mfp's two cents

...on Dynamics AX Development!