0

I saw here edit java bytecode got error that when editing java bytecode with Krakatau ,it may happend to error on stack frames.

The answer there offer to change Krakatau version to 50.

  1. If I only want to edit java byte code(change existing methode) is there any reason to compute stack frame and not use version 50 that not require to compute that?

  2. When I put .stack same the error fix, why?

  3. Version 50 is version of Krakatau ? Is there any disadvantage on this version?

Thank

  • Can you accept my answer please? – Antimony Mar 12 '18 at 17:03
3

Stack maps were a feature added in Java 6 (corresponding to version 50), but were not made mandatory until Java 7 (version 51) in order to ease the transition. Stack maps make classloading slightly faster at the expense of making bytecode generation significantly more painful.

If you are manually editing bytecode, then it is a big hassle to write the stack frames yourself. The easiest solution is to mark your classfiles as version <= 50, in which case you don't have to worry about them at all. The only downside of this is that you can't use features which were added in version 51+ (at the moment, the only notable features that are 51+ exclusive are invokedynamic and modules).

On the flipside, there is one feature, subroutines, which was actually removed in version 50. Therefore, Krakatau defaults your classfiles to version 49 if you don't specify one, because it is the best default version for manually editing bytecode.

If you need to use invokedynamic, then you have no choice but to generate stackmaps as well. You can write them by hand if you want, but it's a pain to do. If you plan to do this, you should familiarize yourself with the JVM specification, which explains how to write stack maps. Krakatau's syntax uses the same names as the specification, so it should be fairly self explanatory.

Alternatively, you can use a tool like ObjectwebASM to do it for you. The only downside of this is that ASM can't handle certain unusual cases. ASM is a tool which is "good enough" for ordinary uses, while Krakatau is designed for power users and tries to handle every bytecode feature and quirk, no matter how obscure. But since stack frames can't be generated automatically in 100% of cases, and Krakatau is oriented towards people who want low level control over the bytecode anyway, it does not attempt to generate stack frames automatically.

Anyway, to answer your questions explicitly,

  1. The only reason not to lower the classfile version to 50 is if you need to use invokedynamic, or other recently added bytecode features.
  2. Because the stack frame you added made the stack map table valid again. The exact frame types and placement you need depends on which changes you make to the bytecode, so .stack same won't always work. If you want to learn how to write stack maps in general, consult the JVM specification.
  3. The classfile version is unrelated to the version of Krakatau. The Krakatau assembler can generate classfiles with any version tag you want, even ones that aren't valid.
  • I done have invokedynamic on the .class file I want to edit. But if I have invokedynamic on another .class file that call to my .class file ( that I edit on version 50) is that can be problem? – Yfsygd Mar 6 '18 at 16:32
  • Nope. Classes with different classfile versions can freely interoperate. – Antimony Mar 6 '18 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.