Tuesday, September 21, 2010

Migrating Flex 3 to Flex 4 pitfalls

It should be fairly easy to compile a project written in Flex 3 in the new Flash Builder 4. However, there are a few pitfalls that I encountered and you may encounter too.

So here they are, plus the solutions.

Before you begin
  • Make sure you are using the latest SDK (currently 4.1)
  • Copy all your old source file, you don't want to ruin them just yet... 
    Create a new project, you will copy most of your old application mxml code there.
  • In Project Properties. Select Flex Compiler on the left, and in "additional compiler arguments" add -theme=${flexlib}/themes/Halo/halo.swc. 
    This will make your application look more or less like it used to when it was under Flex 3 which used the default Halo theme. Of course, if you used a different theme, include that theme instead

    <mx:Application> is now <s:Application>
    <mx:Style> is now <fx:Style>,   <mx:Script> is now <fx:Script>

    Copy your main application mxml and change it.
    In the application tag these namespace attributes should now be:
                   xmlns:fx="http://ns.adobe.com/mxml/2009"
            xmlns:s="library://ns.adobe.com/flex/spark"
            xmlns:mx="library://ns.adobe.com/flex/mx"

    Change <mx:Script> to <fx:Script> on that file, too, and <mx:Style> to <fx:Style>.
    For now, you don't have to do it in ALL your project files, just in the main application mxml.

    If you have global style references, for example you are styling Button in all of your application, you should prefix it with the proper namespace. That is, because Flex 4 has its own button component with the same name.
    So, if you wanna style only your Halo buttons, include in your <fx:Style> tag:
    @namespace mx "library://ns.adobe.com/flex/halo"; 
    and change button to
    mx|Button
    {
       color:#ffffff
    };  

    If you are going to add spark buttons later and want to style them globally too, you will add something like:

    @namespace s "library://ns.adobe.com/flex/spark"; 
    s|Button
    {
       color:#ffffff
    }; 


    Application.application is obsolete

    In Flex 4, you can no longer use Application.application to reference your application. Instead, you now need to use FlexGlobals.topLevelApplication.

    Luckily, in one of the latest Flex SDK 4 builds this is transparent to you as Application.as contains a property called "application" which simply returns FlexGlobals.topLevelApplication.

    So you shouldn't need to change your code (especially if you have this reference all over your code, like I do).

    Application.addChild() WILL fail

    If you try to add an mx container or component to the application itself, it will no longer work with addChild. So use addElement() instead.
    I won't explain here why, but addElement will actually create and add a proper spark container for you and add your component to it.
    If you want to dig deeper on this check out this post (Update: Actually, this post explains this issue).
     
    backgroundImage for Application is no longer supported

    If you used backgroundImage in your old application, you will notice that it's no longer accepted. You will need to use a skin for your application instead Here's how.

    "The style '___________' is excluded by type 'mx.containers._________'."

    If you get this compiler error message it means you fucked up a style in Flex 3, but the old compiler looked the other way - whereas Flex 4 doesn't.
    For example I had this piece of code in my project for some reason:

    <mx:Canvas paddingLeft="0"
    It took me a few seconds to realize that Canvas doesn't even support padding (it's excluded from the class, as you can see in the class's code).

    So just delete these non-existing styles and these errors will be cleared.

    Runtime Error in FocusManger:childHideHandler()

    Once I got my app up and running, it wasn't the end of it. On certain scenarios I would get this runtime error:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at mx.managers::FocusManager/childHideHandler()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\FocusManager.as:1759]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UIComponent.as:12528]
    at mx.core::UIComponent/setVisible()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UIComponent.as:3088]
    at mx.core::UIComponent/set visible()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UIComponent.as:3047] 


    Well, this actually turns out to be a known bug introduced in SDK 4.1, and apparently it was only fixed in Flex SDK 4.5!

    The bug is caused when the focus is set on a component which goes invisible. There are a few alleged workarounds (I tried one or two, but they didn't work in my case).

    One suggestion is to override the event listener for HIDE and invoke event.stopImmediatePropagation().

    If that doesn't work, check out this forum thread for a possible solution.

    Personally, the course of action I took was simply to download 4.5 and use it (I wasn't happy about it, though. I think Adobe should have fixed this back in 4.1. It's not a minor bug).

    mx:GridLines's direction property is obsolete

    Property is now named "gridDirection" :@


    2 comments:

    1. I am in the middle of a migration of a lot of 3.4 SDK projects to Flash Builder 4 with the 4.1 SDK. Here are a few of the common issues I hit which you might want to add to your list:
      1) Accessing ComboBase.textInput. This is now declared as textInput:ITextInput in 4.0. It was textInput:TextInput.
      2) Accessing ViewStack.selectedChild. This is now declared as selectedChild:INavigatorContent. It was selectedChild:Container.
      3) IStroke.apply() now takes 3 arguments. It used to take 1.
      4) And here is a bug/regression that I discovered at runtime with AdvancedDataGrid. It seems that the headerStyleName style is being ignored completely causing all of our headers to be styled incorrectly. This has been filed as JIRA issues FLEXDMV-2329 and FLEXDMV-2489, but I hold little hope that they'll ever get fixed.

      ReplyDelete
    2. We compiled our flex 3 application with flex 4.5 sdk and seeing following critical issue:

      * Our application is mostly customized around the AdvancedDataGrid with customized groupItemRenderers and column level Renderers, The vertical scrolling is causing 'Null Point Exceptions' in set data method of renderers as the value being passed is NULL, The same code works fine with sdk 3.5.

      Please advise/help.

      ReplyDelete

    DermaRoller