I have written a Java bytecode parser using Haskell, and it works just fine. However the next step has me completely stumped.
My Haskell program needs to modify the .class file so that, when executed, the Java program prints:
"Entering [method name here]" before executing a method, and
"Exiting [method name here]" after executing a method.
All I know is that we will need to append the constant pool and method table with calls to System.out.println
, but I feel I'm still missing something.
System.out.println
in bytecode? System.out.println
?Well, this is what the various byte code engineering libraries give you. ASM, BCEL, etc. The specifics of your homework is an aspect, and AspectJ does precisely that.
Sounds like the homework is to write a Haskell byte code engineering exercise, so you will need to mod the class file yourself. Suggestion above by @biziclop is correct. Do a before and after on a class file, note the delta, and do the same yourself from Haskell.
[ps: of course, the above "short-cut" :P is if you don't feel like reading the JVM Spec (as noted in comment to your q) and figuring out how to do it as if you would if writing a Java compiler. You basically call a method by using one of the various byte codes for invoke -- here an interface method call --before which you need to have the receiver e.g. static field out of class System and the method name on the stack. Details in the spec.]
Probably the easiest approach is to write a Java class that has a single method with a System.out.println()
code in it, compile it with javac
and observe the results.
Once you are familiar with it, proceed step by step.
System.out.println()
call somewhere in the java file that you want to instrument. This takes care of the constant pool. Write the Haskell code that finds the relevant constants and injects the bytecode.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With