0

I am searching for this from many weeks but yet didn't got any solution. I want to write a method in a .class file which contains java byte code. I want to take .class file as a text file and write text(method code). I can just write a java code in a .java file but in .class file, it works differently. So, I want to know how java machine reads the .class file and Is this possible to write a new method like this way.

Dhananjay
  • 3
  • 1
  • You can use [bytebuddy](https://bytebuddy.net/#/) to generate bytecode at runtime, but if you want to write plaintext, you'll have to [decompile](https://github.com/pmikova/java-runtime-decompiler) the .class file, [write some plain text into it](https://spoon.gforge.inria.fr), then [compile](https://stackoverflow.com/questions/2946338/how-do-i-programmatically-compile-and-instantiate-a-java-class) it again. As you can see, the latter is a lot more work. – Sweeper Aug 17 '21 at 08:23
  • https://supunsetunga.medium.com/introduction-to-java-bytecode-manipulation-with-asm-9ae71049c7e0 – Alexey R. Aug 17 '21 at 08:26
  • ByteBuddy is for creating classes but I want to modify an existing class file. – Dhananjay Aug 17 '21 at 08:49
  • Thanks @AlexeyR. , Your answer seems working. I will try it – Dhananjay Aug 17 '21 at 08:53

1 Answers1

0

Lombok's @ExtensionMethod might be what you're looking for.

You can add extra functionality to a compiled class.

Before using this on large-scale projects, read why this feature is considered "experimental".

// Because of this annotation "StringExtensions"
// will be applied to all strings referenced in class "LombokExperiment"
@ExtensionMethod({String.class, LombokExperiment.StringExtensions.class})
public class LombokExperiment {
    public static void main(String[] args) {
        String str = "hello";
        System.out.println(str.toTitleCase());
    }

    static class StringExtensions {
        // This is the example from Lombok's docs
        public static String toTitleCase(String in) {
            if (in.isEmpty())
                return in;

            return "" + Character.toTitleCase(in.charAt(0)) + in.substring(1).toLowerCase();
        }
    }
}

Will print Hello.
If you want another class, just replace the String.class at the class-annotation.

The first argument for the function, as mentioned in the documentation is the actual object which will be injected, as you can see in the example, the object is String which corresponds to the String.class at the annotation. You can then alter and return whatever you wish from the function.

Kfir Doron
  • 229
  • 2
  • 5