morvans / as3-commons

Automatically exported from code.google.com/p/as3-commons
0 stars 0 forks source link

Getter interception : targetMethod is null #115

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Hello,

I'm using as3-commons Bytecode 1.0.
In our application, a user can "override" values of some shared business 
objects picked from a company library
As the application contains come legacy, the best way to achieve this point 
seems to create wrapper objects.
If a value is null in the wrapper, the value of the underlying shared object is 
returned.

My interceptor function looks like this :

http://pastie.org/3248809

I create a proxy object this way :
var elementCPI:IClassProxyInfo = proxyFactory.defineProxy(Element);
elementCPI.introduce(tmpclass);
elementCPI.interceptorFactory = new TmpFactory;

The tmpclass is only providing a test findSourceObject() method, and the 
TmpFactory creates a BasicMethodInvocationInterceptor with the interceptor.

When debugging, when the object is created (incoming from server, there is also 
some lines to register the new proxy-wrapper class to a corresponding class 
server-side), a getter is called inside a setter (don't really know why, maybe 
a flex-internal thing as my object is bindable), and during the getter 
interception the targetMethod is null, so I can't check the real proxy-value.
The commented line is a test, resulting in an infinite recursive call.

Thanks !

Original issue reported on code.google.com by h...@anthologique.net on 25 Jan 2012 at 9:52

GoogleCodeExporter commented 8 years ago

Original comment by ihatelivelyids on 25 Jan 2012 at 3:15

GoogleCodeExporter commented 8 years ago
Hi there,

in the 1.0 drop it was indeed impossible to get a reference to the targetMethod 
of a getter or setter (this is technically impossible at the opcode level). We 
hacked around this by adding a privately namespaces method that simply returns 
the getter value, these changes are available in the trunk right now.
Unfortunately I'm not sure if this will resolve your infinite loop issue, I 
think it probably will, since that namespaced method calls the 
supper.getterName to retrieve the value, so that call shouldn't end up in your 
interceptor.

So, try a trunk build and please let me know if that solves anything.

cheers,

Roland

Original comment by ihatelivelyids on 25 Jan 2012 at 3:19

GoogleCodeExporter commented 8 years ago
Hello,

I have the following other NPE error with the last snapshot version (20111214) 
(with reflect 20111101) :

TypeError: Error #1009: Il est impossible d'accéder à la propriété ou à la 
méthode d'une référence d'objet nul.
at org.as3commons.bytecode.proxy.impl::ProxyFactory/buildProxyClass()[ 
C:\projects\as3-commons\as3-commons-bytecode\src\main\actionscript\org\as3common
s\bytecode\proxy\impl\ProxyFactory.as:406]
at org.as3commons.bytecode.proxy.impl::ProxyFactory/generateProxyClasses()[ 
C:\projects\as3-commons\as3-commons-bytecode\src\main\actionscript\org\as3common
s\bytecode\proxy\impl\ProxyFactory.as:302]
at Quantis_client/application1_applicationCompleteHandler()[ 
/opt/quantis/src/Quantis_client/flex_src/Quantis_client.mxml:1120]

Thanks for your reply and for your work,

Christophe.

Original comment by christop...@gtempaccount.com on 30 Jan 2012 at 12:46

GoogleCodeExporter commented 8 years ago
Hi there,

could you post the code where you first do the ByteCodeType scan and afterwards 
call the proxy builder API? I have a fair hunch what's going wrong, the 
ByteCodeType results are stored per ApplicationDomain, so you need to use the 
same application domain reference for both the ByteCodeType call and the proxy 
builder calls.
Check this issue for more info:

https://code.google.com/p/as3-commons/issues/detail?id=111&can=1&q=domain&colspe
c=ID%20SubProject%20Type%20Status%20Priority%20Owner%20Summary%20Milestone

cheers,

Roland

Original comment by ihatelivelyids on 31 Jan 2012 at 8:09

GoogleCodeExporter commented 8 years ago
Hello,

Thanks, it works a bit better now with this for the proxy definition :
var elementCPI:IClassProxyInfo = proxyFactory.defineProxy(Element, null, 
this.loaderInfo.applicationDomain);

Without the introduction, the interceptor contains the getter, so it's OK for 
with part.

But now, another strange issue occurs with the introduction :(
The .introduce() call produce this error :
 Class core.bom.Tempoclass could not be found by ByteCodeType.forName(), unable to introduce
at 
org.as3commons.bytecode.proxy.impl::ClassIntroducer/introduce()[[...]\proxy\impl
\ClassIntroducer.as:84]
at 
org.as3commons.bytecode.proxy.impl::ProxyFactory/buildProxyClass()[[...]\proxy\i
mpl\ProxyFactory.as:430]
at 
org.as3commons.bytecode.proxy.impl::ProxyFactory/generateProxyClasses()[[...]\pr
oxy\impl\ProxyFactory.as:302]

How my things are now ("this" is my application, the code is located in an 
applicationComplete handler):
ByteCodeType.fromLoader(this.loaderInfo);
var proxyFactory:IProxyFactory = new ProxyFactory();
var elementCPI:IClassProxyInfo = proxyFactory.defineProxy(Element, null, 
this.loaderInfo.applicationDomain);
elementCPI.introduce(Tempoclass);
elementCPI.interceptorFactory = new TmpFactory;

Original comment by h...@anthologique.net on 1 Feb 2012 at 1:18

GoogleCodeExporter commented 8 years ago
Hm, I'll have to look into that one, it could be that the proper 
applicationDomain isn't being handed over to the introducer.
I would actually advice not to use the introductions yet though, as stated in 
the documentation there's still a few issues with those. Especially if you use 
them in a release build of your SWF. So if there's a way you can solve your 
problem with just a regular interceptor, I'd go that route if I were you.

cheers,

Roland

Original comment by ihatelivelyids on 1 Feb 2012 at 6:54