ayvango
ayvango

Reputation: 5977

How to modify or substitute private method in a java class

I have a class which behavior I would like to change. I need to replace private method with another realization. Common reflection techniques allow to modify private variable or to invoke private methods. But I find little information about replacing entire methods.

I presume that there are advanced techniques to do so. May be its impossible with standard java reflection but there are probably other tools to recompile byte code in runtime.

Upvotes: 4

Views: 5151

Answers (3)

tucuxi
tucuxi

Reputation: 17945

Modify & replace:

One option is to mask the class with a modified copy (modify code, recompile code, add modified classes to the classpath before patched classes), similar to the approach used here to inspect how a normally unavailable method works.

If you do not have sources to modify, you can "reverse" almost any .class file into more-or-less readable source code using decompilers. Notice that, depending on licensing, you may not have permission to do so and/or to redistribute your changes.

Patch via agent:

You can also patch the methods using the -javaagent:<jarpath>[=<options>] commant-line option. The "agent" is a jar that gets to modify loaded classes and alter their behaviour. More information here.

Mock:

If you have control over where the methods are called, you can replace the target instance with a stubbed version. Libraries such as Mockito make this very, very easy:

LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");

Even though Mockito does not support mocking private methods natively (mostly because it is considered bad manners to look at other classes' privates), using PowerMock allows you to do so (thanks, @talex).

Upvotes: 2

talex
talex

Reputation: 20455

You can't replace method in runtime (at least without hack into JVM). But you can replace whole class. There are several way to do it. For example you can use thing called "aspect".

But from my experience I can say that if you need to do this you have wrong turn somewhere in beginning of you way.

Maybe you better make one step back and look at whole picture

Upvotes: 1

Ashishkumar Singh
Ashishkumar Singh

Reputation: 3600

Instead of going for advanced techniques, there is a simple trick to achieve this.

If you class is part of an open-source jar, get source code of this class file from grepcode.com. Change the method that you want to change and compile it. And update your jar file/classpath with this updated class file.

Upvotes: 0

Related Questions