0

Is there a way in Java using reflection or any, to call a method or a class when a custom method is called.

I have a packed library.jar, in which Foo.class has method doThat(String a, MyObject b)

public class Foo {
    public Object doThat(String a, MyObject b) {
      // do something
      return null;
    }
}

I need a trigger my custom method Bar#doThis, when Foo#doThat is called.

public class Bar {
    public boolean doThis(String a, MyObject b) {
      // did it.
      return true;
    }
}

I will not be able to extract the jar and inject listeners. Foo.class is as similar as java.util.ArrayList or final class java.util.zip.ZipCoder

VenomVendor
  • 15,064
  • 13
  • 65
  • 96
  • https://stackoverflow.com/questions/9664036/how-to-run-two-methods-simultaneously or probably https://stackoverflow.com/questions/18162863/how-to-run-different-methods-parallely ? – Naman Sep 01 '17 at 18:58
  • Where is the Foo instance being used? Are you providing the Foo instance to another object which is calling that method and you need to indirect that? You might be able to wrap the foo instance with a foo subclass that delegates all calls to the foo instance, except for doThat which can trigger a callback, then call mFoo.doThat(); – Selecsosi Sep 01 '17 at 18:58

2 Answers2

0

To expand on my initial question, make a custom subclass that delegates all of foo's calls to the original foo object, except for doThat which you override, call your bar.doThis, and then call the actual foo.doThat. You can do this two ways, first by subclassing the original Foo class if you are creating Foos yourself, or you can just make a wrapper class that straight delegates to a Foo you don't get to create

class SubFoo extends Foo {

    public SubFoo(fooParams..., Bar bar) {
        //...
        this.mFoo = new Foo(fooParams);
        this.mBar = bar;
    }

    @Override
    public Object doThat(String a, MyObject b) {
        this.mBar.doThis(a, b);
        this.mFoo.doThat(a, b);
    }
    //Other methods Foo has that just call into this.foo
}

This should work as long as Foo isn't marked final or you can just delegate straight to foo

class DelegateToFoo extends Foo {

    public DelegateToFoo(Foo foo, Bar bar) {
        //...
        this.mFoo = foo;
        this.mBar = bar;
    }

    @Override
    public Object doThat(String a, MyObject b) {
        this.mBar.doThis(a, b);
        this.mFoo.doThat(a, b);
    }
    //Other methods Foo has that just call into this.foo
}

If Foo has an interface you can just implement that and delegate rather than extending the subclass

Selecsosi
  • 1,636
  • 19
  • 23
0

Looks like what you want to do is intercepting a method execution. This can be done using Aspect Oriented Programming. You have 2 some alternatives like aspectj and Sprint AOP.

When you can intercept any method in before/after or even override it.

Hope this helps.

Jorge Chavez
  • 125
  • 6