Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercepting Java field and method access, creating proxy objects

I want to create such object in Java that will contain some "dispatcher" function like Object getAttr(String name) that will receive all attribute access attempts - so, if I'll do System.out.print(myObj.hello), actual code will be translated to something like System.out.print(myObj.getAttr('hello')), and if I will do myObj.hello = 123, it should execute as myObj.setAttr('hello', 123). Please, note that I should be able to use ANY attribute name, I don't know list of possible names in advance.

So, in this case, is it ever possible?

UPD#1: I'm writing new language for JVM (somehow (J|P)ython-like, so let's call it Jython) with very tight Java integration intented. One of wanted design features is ability to seamlessly access Jython object attributes from Java code just by typing jythonObject.some_attribute. So here is the deal.

Closed: Using AOP via AspectJ seems to be the only possible solution for this, so thank you all for help, and especially Thomas for the most extended answer :)

like image 931
toriningen Avatar asked Sep 13 '26 18:09

toriningen


2 Answers

It is not possible using pure Java, except via:

Bytecode Manipulation

For example using AspectJ.

Annotation Processor

Using a custom annotation processor, which actually is a kind of bytecode manipulation as well. Projekt Lombok is doing something like this.

Synthetic Accessor Method

That is, if the code is anyway using a synthetic accessor method (in which case you could in theory create a proxy):

public class Test {
    public static void main(String... args) {
        TestClass t = new TestClass();
        // this is actually calling a synthetic accessor method
        t.hello = "x";
    }
    static class TestClass {
        private String hello;
    }
}
like image 144
Thomas Mueller Avatar answered Sep 15 '26 10:09

Thomas Mueller


If we stay strictly on OOP grounds, your fields should not be accessible from the outside at all. All field access should be done through get/set methods.

And intercepting methods of an interface is possible via dynamic proxies. (Important note: you can't do it with classes, only interfaces.)

If this doesn't suit your needs (although unless you're writing a third party tool, it probably should) then there's only the messy way, aspect-oriented programming or straightforward bytecode hacking.

It would help if we knew what you need to do this for though.

like image 26
biziclop Avatar answered Sep 15 '26 11:09

biziclop



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!