Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to emit newer class file versions with Scala (50.0/51.0)?

I want to test the new type-checking bytecode verifier with classes created by scalac.

scalac currently outputs version 49.0 class files, but the new type-checking verifier is only mandatory since version 51.0.

I tried to "preverify" the classes with ProGuard (which in fact converted them to version 50.0), but I' not sure if the new verifier just fell back to the old type-inferencing verifier automatically.

How can I convert class files to version 51.0 (or how can I find out which verifier is used when loading version 50.0 class files)?

like image 738
soc Avatar asked Feb 27 '11 20:02

soc


3 Answers

It seems like FJBG (the library NSC uses to generate bytecode) has seen some effort at supporting StackMap but I have no idea how far along it is.

If you ask on scala-internals, Stephane Michelou might pop up. He's the guy who's been working on it.

like image 95
Alex Cruise Avatar answered Nov 18 '22 20:11

Alex Cruise


I am not sure, but I think that bytecode format has not been ever changed deeply and that it is probably always backward compatible. (If you know something about bytecode, remember longs and doubles on constant pool and operand stack, which were designed a bit crazily. It hasn't been modified, has it?) So, changing major/minor number will probably work.

How to do it? There are two ways:

  • Use hexa editor and modify it manually. It should be really simple if you know the position of the bytes. There it the [bytecode specification][1], which says, that you should skip the first four bytes and you will see two bytes of minor version and two bytes of major version (in this order).
  • Use an library. I've some experience with BCEL. It does not seem to be the best designed library which I've ever seen, but it should be good enough for your case. I've seen methods setMinor and setMajor in a class (look at ClassGen and the "almost-immutable" JavaClass).

[1] http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html

like image 39
v6ak Avatar answered Nov 18 '22 20:11

v6ak


I would use ASM to parse the bytecode. I know that scala (and clojure) use ASM internally, so the effort spent to learn it won't be wasted. You can probably throw together a ClassReader and an EmptyVisitor that overrides the visit method that provides header information fairly quickly.

like image 1
Matt Avatar answered Nov 18 '22 19:11

Matt