Forums Register Login

code generation/bytecode modification

+Pie Number of slices to send: Send
I'd like to add a sort of listener to an object, but I need to be able to do this at runtime. My plan is to have a 'dummy' object set whereever it needs to be, and as soon as any of its methods are called, something goes out and sets all the internal values up (anything accessing the object waits until this is finished).

So, I need a way to hijack the object. I can do this by changing the actual object, or by creating a subclass of the object. Either way, I need to put a call to Something at the start of each method, so that that Something can go about setting up the object, and holding off anything that's trying to get at the object while it's doing this.

What's the best way to go about doing this?
+Pie Number of slices to send: Send
This sounds like a job for a Decorator. Here is the Decorator chapter from "Head First Design Patterns".

What I'm suggesting:
- Make a MyClassDecorator class that is a subclass of your existing MyClass.
- MyClassDecorator should have a field of type of type MyClass that gets set with a reference to an ordinary MyClass object in a constructor.
- MyClassDecorator should override each method to call something() and then the method with the same name in the wrapped object.

That way you can add or not add the "something" functionality based on some value available at runtime:



After that snippet, the rest of the code doesn't need to care whether it's dealing with a basic MyClass object or a basic MyClass object wrapped in a MyClassDecorator. They both implement the same basic MyClass interface.

This is a simplification the standard Decorator pattern in that...
  • The pattern is usually used when there is more than one type of additional functionality that might be added.
  • There is usually a separate MyClassDecorator class between MyClass and the various decorators.


  • Since there was only one decorator in this case, I decided to not bother with the extra overhead of the additional intermediate Decorator class.

    I hope this helps.

    Ryan
    +Pie Number of slices to send: Send
    It does help, but I still need to be able to create this decorator at runtime - I can't code this into the classes I'll be setting up, since I don't know what those classes will be. I need to be able to take any class at all, as is, let my factory create it according to whatever, and spit it out - except I won't set it as I create it, I'll just spit out the generated dummy (sub)class (that may or may not be accessed at all, I can't tell) and set it up (via reflection, probably) as soon as anything touches it. So I need to attach a bit of code at the start of all methods that leads into that one method, something like:

    +Pie Number of slices to send: Send
    Would Proxy help? Using Proxy to Interpose on Methods went over my head pretty quickly, but it looks like what you need.
    [ May 09, 2005: Message edited by: Stan James ]
    +Pie Number of slices to send: Send
    That certainly seems to be on the right track, but it looks like that solution is limited to interfaces. I'd still need to deal with classes that don't have an interface.

    I only need to create the class once, so I was considering reading in the classes, creating source code to extend the class, compiling it, and then loading and using that compiled class. That seems really messy though...

    I just started reading http://www-106.ibm.com/developerworks/java/library/j-dyn0916.html , but I don't know if that'll help me or if it's the best solution anyway.
    +Pie Number of slices to send: Send
    Well, I'm pretty sure you could use AspectJ for something like this. Or BCEL if you want to get your hands dirty. Both allow you to essentially rewrite class definitions at runtime. BCEL essentially lets you edit the bytecode directly; AspectJ lets you work at a higher level. You can't make completely arbitrary changes to code with AspectJ, but you can do things like inserting a log statement before all method calls in package X, or insert some new custom method calls before and after calls to method Y() in class Z. I'd look into AspectJ first.
    +Pie Number of slices to send: Send
    those two seem like a lot to take in! I think I have quite a bit of reading to do.

    AspectJ looks like it needs to compile everything with a specific compiler... if this is the case, I'd rather not use it. Is this the case?


    It sure would be nice if I could just write

    and be done with it. But I guess that that's not gonna happen
    +Pie Number of slices to send: Send
    BCEL will do a few things:

    1. Since you're dealing with byte code, it's much faster when the method runs (since it's just executing the calls you added)
    2. Be a pain in the butt to work with. TRUST ME.

    However, if runtime performance is MUCH more important than development ease/speed, go with BCEL.
    +Pie Number of slices to send: Send

    "AmazingToolForDoingThingsToClasses."


    Mind trying Spring AOP ?

    They use cglib for proxying classes and proxies for interfaces but they dont want you to bother
    You can proxy classes for all cases. So you will end up using cglib for everything.




    Do checkout autoproxy feature as well.
    +Pie Number of slices to send: Send
    BCEL, with help from it's BCELifier tool, worked out quite nicely, thanks all for the input.
    I don't get it. A whale wearing overalls? How does that even work? It's like a tiny ad wearing overalls.
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com


    reply
    reply
    This thread has been viewed 1012 times.
    Similar Threads
    Clearing History
    what kind of maths should I know to write java2d and 3d programs?
    Does it make any sence?
    'Generic' and int questions
    Dial UP with Linux
    More...

    All times above are in ranch (not your local) time.
    The current ranch time is
    Mar 29, 2024 04:31:51.