Search code examples
javalogbackinstrumentationjavassist

Javassist insertbefore line number incorrect


I'm injecting a logback logger into jars using Javassist.

In the pattern of logger, I'm recording line number among other details like time, thread, file etc.

The line number of generated log is correct when injected using ctMethod.insertAfter(). But when injected using ctMethod.insertbefore(), the line number is recorded as -1.

Why does this happen? And how can I resolve this?


Solution

  • This happens because Javassist does itself not add any line number information to its code. Within Java byte code, line number information is expressed via information about the start of a line. As Javassist does not change or add such information, it appears as if the insertAfter code is placed on the last line whereas no information is available for the insertBefore code.

    Given some method foo, Javassist would add the code as in the following pseudo code example:

    void foo() {
      // inserted before - in line number information
      // start line number 1
      // original code
      // start line number 2
      // original code
      // inserted after - still on line number 2
    }
    

    As the offset is now placed after the insertBefore code, the latter code does not imply any line number information (expressed by the value -1). As the insertAfter code is implicitly placed after the last offset, it appears as if it was placed within the last line.

    You can avoid this by adding code at the respective line where Javassist adds the code after the line number information using insertAt. Alternatively, you can use Byte Buddy for code manipulation where you can add code using the Advice component. The insertBefore equivalent is the @OnMethodEnter annotation which takes a property prependLineNumber which does do what you want. It is set to true by default.