How to replace a private function

I want to replace a function with a class where I know the source code. The problem is that I cannot redefine the function because it is closed, and I also cannot extend the class and redefine all the functionality, because bad calls are in all possible constructors.

Now I'm completely lost. I don’t know how I can implement this desired functionality (for controlling Android VideoView controls like MediaController). Is there a way to replace the function with reflection or something like that? Or is it even possible not to call the constructor of a superclass, but a super superclass?

Here is a very simple class that shows my problem:

public class Base { public Base(int state) { // must be called } } public class Example extends Base { public Example(int state, boolean bla) { super(state); badCall(); } public Example(int state) { this(state, false); } private badCall() { // doing bad things } } 

Also note that I need to have an instance of Example , so I cannot just copy the class.

+4
source share
3 answers

Here's a contrived example using a mock structure (jmockit). Output:

Original private method
Some other methods
New private method
Another method

 public static void main(String[] args) { A a = new A(); //prints Original private method a.m2(); //prints Some other method new MockUp<A>() { @Mock public void m() { System.out.println("New private method"); } }; A b = new A(); //prints New private method b.m2(); //prints Some other method } static class A { public A() { m(); } private void m() { System.out.println("Original private method"); } public void m2() { System.out.println("Some other method"); } } 
+2
source

You can use AspectJ to access private methods:

 public privileged aspect SomeClassExposerAspect { void around(SomeClass obj) : execution(private void badCall()) { try { // use privileged access to return the private member ((Example )obj).badCall(); } // safeguard against unexpected 3rd party library versions, if using load-time weaving catch (NoSuchMethodError e) { //log something } } } } 

Here is a good blog about it.

+2
source

If you have a source, I suggest you β€œplan” the class.

Compile and create the modified version and replace the old version in the bank or add it earlier to the class path so that it hides the old version.

By the way: you can even patch classes in the JVM this way, although this is rarely a good idea.;)

+1
source

All Articles