Skip to content

filtering JAVAC.CLASS

Evgeny Mandrikov edited this page Jan 9, 2017 · 5 revisions

This page discusses a not yet available feature!

Description

With Java 1.1 class literals have been introduced. With the class keyword java.lang.Class objects can be easily obtained from types. Internally the Class instance is obtained with the Class.forName() method which declares a checked ClassNotFoundException. Therefore the compiler generates a try/catch block that wrapps this exception into a NoClassDefFoundError. In addition the Class object is cached in a synthetic member which results in two branches. As the class can typically loaded this results in uncovered instructions and an uncovered branch, if the line with the literal is executed only once.

Since Java 5 class types can be directly loaded from CONSTANT_Class_info entries of the constant pool, therefore no additional bytecode instructions needs to be generated.

Filtering

All caching and exception handling code should be filtered.

Source Example

java.lang.Integer.class

Bytecode Pattern

For class files ranging from version 45 (Java 1.1) to 48 (Java 1.4):

  GETSTATIC <Owner>.class$<n>
  DUP
  IFNONNULL label_4
  POP
label_1:
  LDC <String "<classname>">
  INVOKESTATIC java/lang/Class.forName(Ljava/lang/String;)
label_2:
  DUP
  PUTSTATIC <Owner>.class$<n>
  GOTO label_4
label_3:
  NEW java/lang/NoClassDefFoundError
  DUP_X1
  SWAP
  INVOKEVIRTUAL java/lang/Throwable.getMessage()
  INVOKESPECIAL java/lang/NoClassDefFoundError.<init>(Ljava/lang/String;)
  ATHROW
label_4:
  ...


Exception Table:
    [label_1, label_2] -> label_3 when : java/lang/ClassNotFoundException