Flex Modules – TypeError: Error #1034: Echec de la contrainte de type : conversion de mx.managers::PopUpManagerImpl@18658d01 en mx.managers.IPopUpManager impossible [Résolu]
Voici un bug Flex que vous allez sûrement rencontrer si votre application comporte plusieurs modules à la fois. Ce n'est pas vraiment un bug en soi, c'est simplement un comportement du Framework Flex qu'il faut connaître pour éviter les surprises.
Le bug en question
Ce bug se produit de nombreuses manières différentes, mais toujours quand vous allez utiliser plusieurs modules dans une même application. Après des actions qui peuvent pourtant sembler banales, vous allez obtenir une RTE (RunTime Error) assez étrange du style:
TypeError: Error #1034: Echec de la contrainte de type : conversion de mx.managers::PopUpManagerImpl@18658d01 en mx.managers.IPopUpManager impossible. at mx.managers::PopUpManager$/get impl()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\PopUpManager.as:68] at mx.managers::PopUpManager$/addPopUp()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\PopUpManager.as:169] at mx.controls::ComboBox/getDropdown()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\ComboBox.as:1459] at mx.controls::ComboBox/displayDropdown()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\ComboBox.as:1552] at mx.controls::ComboBox/downArrowButton_buttonDownHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\ComboBox.as:1801] at flash.events::EventDispatcher/dispatchEventFunction() at flash.events::EventDispatcher/dispatchEvent() at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298] at mx.controls::Button/http://www.adobe.com/2006/flex/mx/internal::buttonPressed()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\Button.as:2504] at mx.controls::Button/mouseDownHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\Button.as:2750] at flash.events::EventDispatcher/dispatchEventFunction() at flash.events::EventDispatcher/dispatchEvent() at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298] at mx.controls::ComboBase/textInput_mouseEventHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\ComboBase.as:1388]
Cette erreur de conversion (Coercion) se reproduit facilement sur le PopUpManager ou sur le DragManager mais peut aussi se produire avec vos propres classes. Vous obtiendrez des messages qui pourront vous sembler étranges. Par exemple:
TypeError: Error #1034: Type Coercion failed: cannot convert MyClass@5d73ce1 to MyClass.
Une conversion de type entre un type MyClass et le même type MyClass qui ne fonctionne pas, il y a de quoi se poser des questions. Ce bug a été maintes fois reporté sur la Bug Base d'Adobe (SDK-16474, SDK-14384, ...) mais peut facilement être corrigé.
Un exemple d'application qui pose problème
J'ai monté rapidement une application qui expose ce problème. Voici le code:
L'application principale
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:ModuleLoader url="Module1.swf"/> <mx:ModuleLoader url="Module2.swf"/> </mx:Application>
Le premier module (Module1)
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Label text="Module1.swf"
fontWeight="bold"
fontSize="14"/>
<mx:ComboBox>
<mx:dataProvider>
<mx:String>Module1-A</mx:String>
<mx:String>Module1-B</mx:String>
<mx:String>Module1-C</mx:String>
<mx:String>Module1-D</mx:String>
</mx:dataProvider>
</mx:ComboBox>
</mx:Module>
Le second module (Module2)
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Label text="Module2.swf"
fontWeight="bold"
fontSize="14"/>
<mx:ComboBox>
<mx:dataProvider>
<mx:String>Module2-A</mx:String>
<mx:String>Module2-B</mx:String>
<mx:String>Module2-C</mx:String>
<mx:String>Module2-D</mx:String>
</mx:dataProvider>
</mx:ComboBox>
</mx:Module>
Rien de bien complexe, simplement 2 modules avec une ComboBox chacun. Dans l'exemple ci-dessous, ouvrez la première ComboBox puis la deuxième. Si vous avez le Flash Player Debugger, vous obtiendrez l'erreur dont on parle dans cet article.
L'application en ligne
Flex Source Code Download: Télécharger le code source complet de l'application
La raison du problème
Lorsqu'il se produit sur des classes internes du framework Flex (PopUpManager, DragManager, HistoryManager, ...), ce bug est du à la gestion des Singletons dans Flex. En fait, quand les modules sont chargés, les classes contenues dans ce module sont ajoutées au domaine enfant de l'applicationDomain courant. Donc les classes qui font parties du modules seront possédées par le module et pas par l'application.
Cela crée un problème quand 2 modules essaient d'utiliser la même classe. Quand le module est chargé pour la première fois, sa définitions de classe est enregistrée et le module qui sera chargé plus tard va se rendre compte que la définition de classe qu'il contient ne correspond pas à celle qui a été enregistrée. Dans le cas des combobox, c'est la définition de IPopUpManager qui pose problème mais vous auriez le même problème de conversion avec deux modules ayant du Drag And Drop avec le DragManager.
La solution au problème
La solution est très simple mais peut pourtant nuire à la modularisation de votre application. Pour combler ce bug, il suffit de déclarer dans l'application principale, les classes qui vont être partagées par plusieurs modules. Pour être sûr de votre coup, il vous suffit de mettre ce code dans l'application principale:
import mx.managers.PopUpManager; import mx.managers.DragManager; import mx.managers.HistoryManager; private var _linkage:Array = [PopUpManager, DragManager, HistoryManager];
Si vous utilisez vos propres classes, et que vous devez y accéder depuis plusieurs modules, il faut aussi les ajouter à la liste avec l'import correspondant.
Articles similaires
- Flex Modules – Communication entre Module et Application
- Flex Modules – Créer une application Flex modulaire
- Flex Modules – Communication Module vers Module
- Flex Modules – Utiliser des interfaces ActionScript pour communiquer avec l'application
- Flex Localization – Chargement de Resource Modules à la volée
Aucun trackbacks pour l'instant






1 novembre 2009
Pourrais-tu poster le lien vers les sources de l'application et un court commentaire sur comment s'en servir à la suite du bug [#SDK-16474] dont tu parles, un des développeurs affirme ne pas arriver à le reproduire. Je n'ai pas osé le faire à ta place.
Merci pour ça, pour cet article et la suite de billets sur les modules, il y a plein de choses intéressantes.
1 novembre 2009
Salut,
le lien vers les sources de l'application est juste au dessus de l'exemple (View Source ne fonctionne pas à cause de ma redirection http pour WordPress). Pour le dev (Peter deHaan Adobe je présume) qui n'arrive pas à le reproduire, cela fait plus d'un an et en plus, le commentaire suivant explique comment résoudre ce bug.
Je vais rajouter cela sur la bug base quand même
Merci
Fabien
1 novembre 2009
C'est bon c'est fait:
https://bugs.adobe.com/jira/browse/SDK-16474
Fabien
16 novembre 2009
Merci bcp , excellent travail
20 décembre 2009
Merci Fabien pour cette solution!
Je ne comprenais pas d'où cela venait...
4 mars 2010
Merci beaucoup, votre site m'as vachement aidé.
1 décembre 2010
Merci, ça m'a bien aidé !
6 avril 2011
Merci,
bientôt 1h que je farfouillais mon code.
Pb résolu!
(je consulte ton blog depuis 2009)!
6 avril 2011
Salut ben,
content d'avoir pu aider
Fabien
6 juillet 2011
OH MY GOD !!!!
merciiiiiiiiiiiiiiiii j'ai passé 2h à chercher pourquoi mes le déchargement des modules provoqué cette erreur !
P.S.: Mon problème venait du fait de chargé et décharger les même module.