1

I have class file has a method like this:

public boolean validate(String str) {}

There're lots of codes inside this validate method, but I only want to make it always return true or false. Can someone point me out how to modify a class file to achieve this?

4 Answers 4

5

RULE override rtn CLASS Foo METHOD validate IF true DO RETURN true ENDRULE

http://www.jboss.org/byteman

Sign up to request clarification or add additional context in comments.

1 Comment

Your solution is interesting, I'll give a try. But anyway, you're the only one understand my question, thanks.
2

Are you trying to unit test this code and force an answer without caring about the conditions? If that is the case, then you are looking for "Mocking" frameworks. In Java, I can think of Mockito and EasyMock off of the top of my head.

Relatedly, you can use PowerMock (works in tandem with either of the above Mocking frameworks) to dynamically change classes (such as final classes/methods, static methods, and even private pieces of classes). PowerMock actually can change the byte code when necessary. Check under its classloading folders.

I've never considered it, but it might be possible to use any of them within non-test code, but they may require finagling to avoid JUnit dependencies (such as JUnit Runner). Again, I have never thought about it, so I never thought through the implications.

At the very least, you can probably look through PowerMockito to see how they change the byte code.

If you just want to unit test, then it's extremely easy and you probably don't need to worry about the byte code.

public class SomeClass {
    public boolean validate(String s) {
        // tons of logic
    }
}

Test (using Mockito with JUnit 4 (drop the @Test attribute for JUnit 3)):

private final MyClassBeingTested testClass = new MyClassBeingTested();

@Test
public void testMyCodeWithSomeClass() {
    SomeClass some = mock(SomeClass.class);

    when(some.validate(anyString())).thenReturn(eq(true));

    // whenever it uses "some.validate()", with any
    //  string, then it will return true
    testClass.useSomeClass(some);

    // assert whatever conditions you want

    // if you care to ensure that it called validate:
    //  note: times(1) is implied if not supplied, but times(0), times(2), etc.
    //  could be used ("never()" exists as a synonym for times(0))
    verify(some, times(1)).validate(anyString());
}

Comments

1

It can only return true or false, according to the method signature provided.
Can you make a wrapper class that delegates calls to the original and overrides the behaviour that you require, instead of trying to manipulate the bytecode?

1 Comment

No. This method is called internally. Not controlled by me. It's kind of hacking approach.
1

The simplest way to modify the byte code is to decompile the class or get a copy of the source code. Change the code and compile it. Put the new version earlier in the classpath or replace the original in the jar. This way you have changed the method.

You can change it at runtime, but that is 100x harder. ;)

5 Comments

How does one force the decompiled code to recompile, though? I've had very poor luck with it on large projects where only one class needs editing but I am forced to compile the whole thing due to dependencies.
@Wyatt8740 it depends on how serious you changes are, but you should be able to re-compile just one class, even though the tools might not know you don't need to re-compile.
Hm, I was just making a method return '0'. But javac needed other source files apparently. Maybe there was inheritance involved or something. I was not using an IDE or build sytem; just the java compiler from the command-line.
@Wyatt8740 if you need other source files you are doing more in that class the returning 0. In any case you should be able to compile it using the JAR you extracted the class file from.
what exactly do you mean? How would I make the compiler use those .class files instead of trying to compile everything fresh?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.