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?
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
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.
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.