0

I need to change existing compiled .class file. Actually I have even sources of it, but I cannot just change and recompile it because of many dependencies that I don't have.

So I need to change 2 methods. Both them have void return type. The first contains just 2 lines that are calls of another methods of the same class, i.e.

public void a() {
    System.out.println("a");
}

public void b() {
    System.out.println("b");
}

public void ca() {
    a();
    b();

}

And I need to change method ca sp that it calls only a() method.

The second method that I need to change contains some logic, but I want to clear it at all, i.e. to have method with empty body that does nothing.

How can I do this?

Mikhail
  • 1,583
  • 5
  • 22
  • 34

9 Answers9

2

If you don't have the required dependencies, how are you expecting to use this code? I would strongly recommend that you devote your time to being able to compile this normally, instead of trying to just change the binary. It's likely to be a better bet in the long run.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • >> how are you expecting to use this code? This class is a part of a big application that we need to change. But all dependencies are located on the customer side and we cannot get them – Mikhail Mar 04 '11 at 09:32
  • @Mikhail: So why don't you have the dependencies, or why can't you get hold of them? Trying to go forward with only part of a working environment really isn't a good idea. – Jon Skeet Mar 04 '11 at 09:33
  • 3
    A further question, how will you test your changes before giving the code to the customer? – Peter Lawrey Mar 04 '11 at 09:39
1

I would take a look at AspectJ and set triggers to every call of ca. Then you can easily block that call and call a instead.

1

Try this question on Java Bytecode editors.

java bytecode editor?

However, I think Jon Skeet's answer is the one that really applies here.

Community
  • 1
  • 1
JeremyP
  • 84,577
  • 15
  • 123
  • 161
0

You can use a java decompiler for opening the class file and edit it and save it.

Here's one good decomp --> http://java.decompiler.free.fr/

0

I am not sure if you can change it in the first place, but even if you did succeed, I wouldn't recommend that. A cleaner solution would be to extend your class and override the implementation of the ca() method to call only the a() method.

adarshr
  • 61,315
  • 23
  • 138
  • 167
  • I cannot do this because this class is a part of application that I cannot re-write to use my new class. – Mikhail Mar 04 '11 at 09:30
0

If method a is public then the easiest way is to use an aspect (Aspect Oriented Programming, AspectJ) and intercept every call to ca. Instead of invoking ca just invoke a.

Boris Pavlović
  • 63,078
  • 28
  • 122
  • 148
  • This is a good idea but I cannot add aspects to the application that I need to change. Anyway thanks! – Mikhail Mar 04 '11 at 09:32
  • Do not change the app at all. Manipulate it with aspects. If you are not allowed to use aspects then it's a completely other thing. – Boris Pavlović Mar 04 '11 at 09:33
0

Have you tried looking into reflection? I have limited experience with it, but I'm not sure what you want to do it possible.

Dean Barnes
  • 2,252
  • 4
  • 29
  • 53
0

You can use Javaasist library to modify existing class file.

Andrey Adamovich
  • 20,285
  • 14
  • 94
  • 132
0

I had a similar problem.

I had to modify a method in a class file with no source. The method was rethrowing the exceptions badly so I had to tweak it. I have decompiled the class with Classfile Analyzer (http://classfileanalyzer.javaseiten.de/) I have edited then the resulted file and recompiled it with Jasmine assembler.

Using Apache BCEL you can accomplish the same thing but in a more elegant way - at runtime - not as I have described above at compile time.

Daniel Voina
  • 3,185
  • 1
  • 27
  • 32