7

I am developing a dynamic mocking framework for Flex/AS3 and am having trouble with private/support types (ie. those declared outside the package {} in a class file).

In my ABC "file", I am declaring the instance with the PROTECTED_NAMESPACE class flag and with a PRIVATE_NS multiname. I have also experimented with giving it the same namespace as the class it is subclassing (eg. PRIVATE_NS("ContainerClass.as$123")).

No matter what I do, I always get the following error after loadBytes:

VerifyError: Error #1014: Class ContainerClass.as$123::PrivateClass could not be found.

I have experimented with loading the generated bytecode into the same ApplicationDomain as the private class (I use a child domain by default). I even tried registering a class alias before the load (though that was a bit of a stretch).

Am I forgetting anything or is it simply a restriction of the AVM?

Please note that I am fully aware that this is illegal in ActionScript 3.0, I am looking for whether this is actually possible in the AVM.

Edit: For those interested in the work so far, the project is asmock and is on sourceforge.

Richard Szalay
  • 83,269
  • 19
  • 178
  • 237

3 Answers3

1

I'm no expert with ABC files but I just don't think this is possible in the AVM2. I did several tests a while ago with the AS3 Eval lib and they all failed.

Related to dynamic mocking, I have filed an issue in Adobe bugbase, asking for a dynamic proxy mechanism: http://bugs.adobe.com/jira/browse/ASC-3136

Christophe Herreman
  • 15,895
  • 9
  • 58
  • 86
1

I'm not sure what you mean by PRIVATE_NS("ContainerClass.as$123"), My reading of avm2overview.pdf 4.4.1 is that private namespaces are not permitted to have a name, hence that the "<class name>$<number>" namespace in debug output is generated for your convenience. I would assume that would mean you would have to hack your abc into the same abc tag in the source swf to access the namespace constant index (and that sounds too much like hard work to me!)

I haven't actually managed to generate a loading swf, though, so take this with a grain of salt.

Simon Buchan
  • 12,707
  • 2
  • 48
  • 55
  • 4.4.1 designates that SYSTEM namespaces are empty (ie. String, int, etc), but private namespaces (ie. those with a multiname kind of PrivateNs/0x5) still have names) still have values. .as$ is automatically allocated as the (private) multiname to nested classes. – Richard Szalay Mar 09 '09 at 09:09
  • Also, the framework that I'm working does generate a loading swf and supports generation of all types of classes (including Vector.). It's only the "nested" classes that are causing me grief. If you are interested in the work so far, the source is available at http://asmock.sourceforge.net – Richard Szalay Mar 09 '09 at 09:10
  • "User-defined namespaces have kind CONSTANT_Namespace or CONSTANT_ExplicitNamespace and a non-empty name. System namespaces have empty names and one of the other kinds" is the text I'm thinking of here. This implies CONSTANT_PrivateNs is a system NS, and has no stored name. – Simon Buchan Mar 10 '09 at 05:01
  • And I'm thinking you might have to parse in the abc tag from the swf, merge in your generated code and splice it back into the swf (in memory). Of course, you won't be able to do this within the swf you are mocking :(. – Simon Buchan Mar 10 '09 at 05:04
  • I guess it will have to wait for when I refactor my reflection lib to parse the abc tag. I wonder if the type assignment will work if it's declared in multiple application domains. – Richard Szalay Mar 18 '09 at 13:48
  • I might not have been clear: from my understanding, PrivateNs's are private because they are not referenceable outside the tag. You would have to parse the incoming swf, and modify the abc tag to include your mock class *before* loading: meaning only one App Domain. – Simon Buchan Mar 19 '09 at 23:38
  • Ah, I see what you mean. Unfortunately that's not feasible as the swf in question would have already been loaded (it's a runtime dynamic mocking framework). Thanks for the clarification! – Richard Szalay Mar 23 '09 at 20:04
0

Having gone back to look at this problem in ernest, I can definitively answer this question: private classes can only be referenced from the LoaderContext that loaded them

I have been able to add support for private interfaces by reproducing the interface in the loaded ABC 'file', but it cannot be coerced/cast back to the original private interface.

This is still useful for my requirements, as a private interface can be used to combine multiple interfaces.

Richard Szalay
  • 83,269
  • 19
  • 178
  • 237