Flex Parsley silent failure

I have been recently having many silent failures in my parsley project and was wondering what must be causing it. While I was fairly doubting on the way I have configured my objects in context I was still looking to find a legit answer to this issue. And for a (no) surprise I have found answer in Parsley documentation it self. Some of you might be aware of this but still reading section 15. Troubleshooting Guide is useful and  must for all parsley developers. I have copied segment which explains silent failures

15.2 Silent Failure

Even after you have configured logging as described in the preceding section, you still might run into a situation where an expected action is not performed while the logging output remains completely silent about it. Since Parsley generally logs all errors this usually hints at a problem where the framework does not even attempt to perform the desired action. This is usually caused by some sort of configuration error. The following sections list the most common scenarios that lead to silent failure:

The object is not managed

Some developers new to the concept of IOC containers simply add metadata like [Inject] to a class and then create an instance with new and are suprised that nothing happens. Such an instance is not known to the framework and thus will never get configured. Another common error is to add the class to a Parsley configuration file or class as required and then create an instance with new. This is a similar problem: Now you have two instances of the same class, but the one you created with new is not managed by the framework.

If you are not familiar with the concept of managed objects, please read 7.1 About Managed Objects first.

If you are not sure whether the object you are working with is managed, you can use the framework API to find out:

var obj:SomeClass = ...; // the object that does not work trace("managed? " + ContextUtil.isManaged(obj)); 

Apart from that you’ll also find logs for all objects that are getting added or removed from a Context. They look like this:

21:09:07.967 [INFO] org.spicefactory.parsley.core.lifecycle.impl.DefaultManagedObjectHandler Configure managed object with [ObjectDefinition(type = com.foo::MyClass, id = someId)] and 2 processor(s) 

Metadata not compiled into the SWF or SWC

Another very common error. The mxmlc compiler of the Flex SDK has a confusingly inconsistent behavior when it comes to compiling metadata into SWFs. The outcome is different whether you merge Parsley into the code or whether you specify it as an external library. As a consequence it usually works in the top level application without additional configuration steps, but then fails when used in a Flex Module for example.

To find out whether metadata has actually been compiled into your application, you can trace the reflection output of the Flash Player for that class:

var obj:SomeClass = ...; // the object that does not work trace(describeType(obj)); 

Here you can see whether the metadata is present on the property or method where you expect it. For Flex Modules or RSLs the metadata usually has to be specified explicitly. For detailed instructions see 3.1 Configuration with AS3 Metadata, specifically the section titled Compiling custom metadata into SWFs.

Metadata on private or protected members

The Reflection facility in the Flash Player will only consider metadata on public members. This is not a limitation of the Parsley framework, it’s the way the Flash Player works. Thus the following will simply be ignored, you won’t get any error messages:

[Inject] private var service:RemoteObject; 

Typos in metadata

Although this is pretty obvious it’s worth mentioning it as this also leads to silent failure. When you misspell an attribute on a Parsley metadata tag the framework will throw an Error, but if you misspell the tag name itself it will simply get ignored.

Timing issues with object initialization

Also a pretty common scenario. The dependency injection does get performed in this case, just not at the time the developer expects it. The most extreme example is trying to access the value of a variable marked with [Inject] in the constructor of an object. It should be pretty obvious that it is virtually impossible that the injection has already happened at this point.

Somewhat less obvious but still very common is to use a Flex component event like addedToStage orcreationComplete and then access an expected injected value in the event handler. Please don’t do this! There are lots of reasons not to use addedToStage for component initalization, some of them are not even related to Parsley. For the full story, please read 8.7 Component Lifecycle and specifically the section titled Be careful with Component Initialization Logic.

As a very short excerpt of that section, a safe place to put some initialization logic is a method marked with [Init]. This will only be invoked after all injections have been performed:

[Inject] public var service1:SomeService; [Inject] public var service2:SomeOtherService; [Init] public function init () : void { // here it is guaranteed that service1 and service2 have been set already
Advertisements

Tags: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: