java - What bytecode library when controlling line numbers? -
i need generate new classes (via generation of java byte code) existing classes. analyse body (expressions) of methods of class. expressions determine code generate.
for me importand set source file new classes (same base java file) controlling line numbers (when exception thrown stacktrace should contain line numbers of base java file).
example: have file baseclass.java. compiler generates baseclass.class this. i'd analyse class file , generate byte codes generatedclass.class. when @ c exception thrown stacktrace should contain "baseclass.java line 3".
baseclass.java 1: class baseclass { 2: void method() { 3: call(); 4: } 5:} generatesclaas.class a: class generatedclass { b: void generatedmethod() { c: generatedcall(); d: } e:}
my question: there libraries support requirement? javassist, asm or bcel? use purpose? hints how or example code helpfull.
edit: hints library not use because requirement can not fullfiled helpfull, :).
with asm, can use methods visitsource , visitlinenumber create debugging information in generated class.
edit: here minimal example:
import java.io.file; import org.objectweb.asm.label; import org.objectweb.asm.methodvisitor; import java.io.fileoutputstream; import java.io.ioexception; import org.objectweb.asm.classwriter; import org.objectweb.asm.util.checkclassadapter; import static org.objectweb.asm.opcodes.*; public class app { public static void main(string[] args) throws ioexception { classwriter cw = new classwriter(0); checkclassadapter ca = new checkclassadapter(cw); ca.visit(v1_5, acc_public + acc_super, "test/test", null, "java/lang/object", null); ca.visitsource("this/file/does/not/exist.txt", null); // not sure second parameter methodvisitor mv = ca.visitmethod(acc_public | acc_static, "main", "([ljava/lang/string;)v", null, null); mv.visitcode(); label label = new label(); mv.visitlabel(label); mv.visitlinenumber(123, label); mv.visittypeinsn(new, "java/lang/runtimeexception"); mv.visitinsn(dup); mv.visitmethodinsn(invokespecial, "java/lang/runtimeexception", "<init>", "()v"); mv.visitinsn(athrow); mv.visitinsn(return); mv.visitmaxs(2, 1); mv.visitend(); ca.visitend(); file target = new file("target/classes/test/"); target.mkdirs(); fileoutputstream out = new fileoutputstream(new file(target, "test.class")); out.write(cw.tobytearray()); out.close(); } }
running generates class containing main method throws runtimeexception see line number in stack trace. first lets see disassembler makes of this:
$ javap -classpath target/classes/ -c -l test.test compiled "this.file.does.not.exist.txt" public class test.test extends java.lang.object{ public static void main(java.lang.string[]); code: 0: new #9; //class java/lang/runtimeexception 3: dup 4: invokespecial #13; //method java/lang/runtimeexception."<init>":()v 7: athrow 8: return linenumbertable: line 123: 0 }
so class compiled txt file not exist :), linenumbertable says bytecode starting @ offset 0 corresponds line 123 of imaginary file. running file shows file , linenumber contained in stack trace:
$ java -cp target/classes/ test.test exception in thread "main" java.lang.runtimeexception @ test.test.main(this/file/does/not/exist.txt:123)
Comments
Post a Comment