Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing fields from a proxied object

I've run into an interesting problem while developing an ORM framework for Android. I'm using a library called dexmaker for bytecode manipulation, which enables me to create proxies for persistent objects in order to implement lazy loading.

The proxied instance has an associated InvocationHandler such that when a method is called on the proxy, the invoke method is called on the InvocationHandler, which then calls the proxied object's respective method assuming it's been lazily loaded. Nothing too surprising -- it's just like Java's Proxy class but allows me to proxy actual classes instead of interfaces (see dexmaker's ProxyBuilder).

The part that's become problematic is that I also use reflection to retrieve field values from persistent objects and -- now that I've introduced lazy loading -- proxies. Here is what I'm currently doing:

for (Field f : getPersistentFields(model.getClass()) {
    ...
    Object val = f.get(model); // model is either a persistent object or a proxy for one
    mapField(f, val, map);
}

This of course works for regular model instances, but for proxied instances, f.get(model) is not retrieving the proxied object's field value. Instead, it's returning the default value assigned in the class's constructor. The access on the proxy's field is not being intercepted obviously.

My question is this: is there any way I can intercept an access on a proxy's member variable made through reflection? If not, how can I retrieve the value of a proxy's field in a "reflection-like" way?

One possible workaround I'm thinking of would be to retrieve and then invoke the field's getter method using reflection, but I'm wondering if there's a more direct solution. This workaround, if it actually works, would require the object to have a getter method for all persistent fields -- a requirement that should typically be followed from an OO-design point of view but also forces more work onto the user of the framework.

I'm open to any ideas.

like image 532
Tyler Treat Avatar asked Mar 14 '12 01:03

Tyler Treat


1 Answers

A good solution is to access the fields using setter/getters rather than using Field class. (I believe this is more than a workaround)

On the other hand, if you want to go with the direct field accessing approach. As far as I see there is no easy way to intercept field accesses. Please check the answers to this question. Altough the question is related with intercepting field modification rather than reading the field, it may provide some insights and direction.

like image 73
Hakan Serce Avatar answered Nov 01 '22 02:11

Hakan Serce