Atos
Atos

Reputation: 717

Determine whether .class file was compiled with debug info?

How can I determine for any Java .class file if that was compiled with debug info or not?

How can I tell exactly what -g{source|lines|vars} option was used?

Upvotes: 40

Views: 12323

Answers (3)

Joshua Goldberg
Joshua Goldberg

Reputation: 5333

Building on the two answers above (Aaron Digulla and Pete Kirkham), you can inspect the jarfile or the classfile directly with javap -v. I find this a little simpler than using a classpath. Single quotes are needed with the ! for the jarfile case.

javap -v 'jar:file:///Absolute/Path/To/JarFile.jar!/package/name/using/slashes/ClassName.class' | grep "\(Compiled from\|LineNumberTable\|LocalVariableTable\)" | head

or (don't need the absolute path for checking a classfile)

javap -v Path/To/ClassName.class | grep "\(Compiled from\|LineNumberTable\|LocalVariableTable\)" | head

If results are unclear or the format changes, pipe to less instead of grep and take a look.

Upvotes: 0

Aaron Digulla
Aaron Digulla

Reputation: 328556

You must check the Code structure in the class file and look for LineNumberTable and LocalVariableTable attributes.

Tools like ASM or Apache Commons BCEL (Byte Code Engineering Library) will help: https://commons.apache.org/proper/commons-bcel/apidocs/index.html?org/apache/bcel/classfile/LineNumberTable.html

Upvotes: 2

Pete Kirkham
Pete Kirkham

Reputation: 49311

If you're on the command line, then javap -l will display LineNumberTable and LocalVariableTable if present:

peregrino:$ javac -d bin -g:none src/Relation.java 
peregrino:$ javap -classpath bin -l Relation 
public class Relation extends java.lang.Object{
public Relation();

peregrino:$ javac -d bin -g:lines src/Relation.java 
peregrino:$ javap -classpath bin -l Relation 
public class Relation extends java.lang.Object{
public Relation();
  LineNumberTable: 
   line 1: 0
   line 33: 4

peregrino:$ javac -d bin -g:vars src/Relation.java 
peregrino:$ javap -classpath bin -l Relation 
public class Relation extends java.lang.Object{
public Relation();

  LocalVariableTable: 
   Start  Length  Slot  Name   Signature
   0      5      0    this       LRelation;

javap -c will display the source file if present at the start of the decompilation:

peregrino:$ javac -d bin -g:none src/Relation.java 
peregrino:$ javap -classpath bin -l -c Relation | head
public class Relation extends java.lang.Object{
  ...

peregrino:$ javac -d bin -g:source src/Relation.java 
peregrino:$ javap -classpath bin -l -c Relation | head
Compiled from "Relation.java"
public class Relation extends java.lang.Object{
  ...

Programmatically, I'd look at ASM rather than writing yet another bytecode reader.

Upvotes: 47

Related Questions