1

I'm trying to override a method for a class that is used in an API without extending it. Is there any way to do this without recompiling the source code? I cannot extend the class because its instance is created inside another class and there are also other classes that need to extend it.

Example:

    import A,B,C;

    public class Tester{
    public static void main(String[] args){

    A a = new A();
    a.getB().method();
    //The object I want to handle is A
    //A has-a B and C
    //C extends B and is used at some point inside B
    //how can I override method() in B?
        }
    }

^ Addressing this problem is all I need

If you want to take a look at the specific problem, I'm using the htmlunit API and I'm trying to override the onAllChildrenAddedToPage() method in DomNode. The DomNode is used by the WebClient class and needs to be cast into HtmlElement at some point inside WebClient and DomNode. I making a DomNode2 (which extends DomNode) after getting its instance from WebClient, but it gave a ClassCastException because DomNode2 cannot be cast into HtmlElement.

  • I don't see why extending DomNode and overriding onAllChildrenAddedToPage() causes ClassCastException. But looking at the htmlunit API, HtmlElement extends DomNode. So your DomNode2 can extend HtmlElement and override onAllChildrenAddedToPage(). This would solve your ClassCastException problem because someone is trying to cast your object to HtmlElement. – anonymous Feb 21 '14 at 01:23
  • I just tried extending HtmlParagraph (wasn't HtmlElement that gave me the error, my bad) and it still gave the ClassCastException error for some reason. I gave DomNode2 a constructor, called the super and put them in the same package. It's really weird. Exception in thread "main" java.lang.ClassCastException: com.gargoylesoftware.htmlunit.html.HtmlParagraph cannot be cast to com.gargoylesoftware.htmlunit.html.DomNode2 – user3335154 Feb 21 '14 at 02:19
  • May I ask what are you trying to achieve in a bigger picture? Maybe also post some of your code. – anonymous Feb 21 '14 at 02:25

1 Answers1

0

There's no easy way to do this without recompiling the source code. Are you absolutely sure that what you're trying to do is necessary? If you are, consider recompiling the source with your own custom method, as HtmlUnit is open source.

If you really don't want to recompile, you can also try editing the byte code of the class using ASM. This is fairly difficult though, and not a really good practice.

If you only need to add code to the method, you could use method interceptors to run code when the method is invoked. Check out this question on method interceptors for more information on how to do that.

Community
  • 1
  • 1
kabb
  • 2,474
  • 2
  • 17
  • 24
  • Yeah, I have to override the method because what I want to do is being called recursively inside DomNode and the recursion is reversed from what I want (the parent nodes call child nodes so the child nodes get processed first). ASM looks too difficult, I'll try the method interceptors and editing the source code if that doesn't work. Thanks. Though if anyone else has any other solution, I'd like to hear it. :) – user3335154 Feb 21 '14 at 01:33