-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
8u45
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin Kernel Version 15.0.0: Wed Aug 26 16:57:32 PDT 2015; root:xnu-3247.1.106~1/RELEASE_X86_64
A DESCRIPTION OF THE PROBLEM :
given:
i've got class P that extends class B. ie:
public class P extends B {
static {
System.out.println("HELLO It's P");
}
}
public class B {
static {
System.out.println("HELLO It's B");
}
public Object load(Object key) throws Exception {
return getClass();
}
}
in system there is java agent that register class transformer and logs all loaded classes.
when:
i'm creating class instances dynamically:
Class.forName("P", true, getClass().getClassLoader()).newInstance();
Class.forName("B", true, getClass().getClassLoader()).newInstance();
(or even using just new P();)
failure:
ERROR: class B is not transformed
output is as follows:
ClassFileTransformer: Class loaded: P
HELLO It's B
HELLO It's P
expected behavoiur
when i change the invocation order everything is ok:
ClassFileTransformer: Class loaded: B
HELLO It's B
ClassFileTransformer: Class loaded: P
HELLO It's P
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. add to system java-agent that logs ClassFileTransformaton invocations
2. create classes as in example above
3. create instance of derived class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
base class should always be transformed by ClassFileTransformer
ACTUAL -
base class is not transformed by ClassFileTransformer if some of it subclasses is instantiated first
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
File P.java
public class P extends B {
static {
System.out.println("HELLO It's P");
}
}
File B.java
public class B {
static {
System.out.println("HELLO It's B");
}
public Object load(Object key) throws Exception {
return getClass();
}
}
File Main.java
public class MainClass {
public static void main(String[] args) {
try {
Class.forName("B", true, MainClass.class.getClassLoader()).newInstance();
Class.forName("P", true, MainClass.class.getClassLoader()).newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
---------- END SOURCE ----------
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin Kernel Version 15.0.0: Wed Aug 26 16:57:32 PDT 2015; root:xnu-3247.1.106~1/RELEASE_X86_64
A DESCRIPTION OF THE PROBLEM :
given:
i've got class P that extends class B. ie:
public class P extends B {
static {
System.out.println("HELLO It's P");
}
}
public class B {
static {
System.out.println("HELLO It's B");
}
public Object load(Object key) throws Exception {
return getClass();
}
}
in system there is java agent that register class transformer and logs all loaded classes.
when:
i'm creating class instances dynamically:
Class.forName("P", true, getClass().getClassLoader()).newInstance();
Class.forName("B", true, getClass().getClassLoader()).newInstance();
(or even using just new P();)
failure:
ERROR: class B is not transformed
output is as follows:
ClassFileTransformer: Class loaded: P
HELLO It's B
HELLO It's P
expected behavoiur
when i change the invocation order everything is ok:
ClassFileTransformer: Class loaded: B
HELLO It's B
ClassFileTransformer: Class loaded: P
HELLO It's P
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. add to system java-agent that logs ClassFileTransformaton invocations
2. create classes as in example above
3. create instance of derived class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
base class should always be transformed by ClassFileTransformer
ACTUAL -
base class is not transformed by ClassFileTransformer if some of it subclasses is instantiated first
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
File P.java
public class P extends B {
static {
System.out.println("HELLO It's P");
}
}
File B.java
public class B {
static {
System.out.println("HELLO It's B");
}
public Object load(Object key) throws Exception {
return getClass();
}
}
File Main.java
public class MainClass {
public static void main(String[] args) {
try {
Class.forName("B", true, MainClass.class.getClassLoader()).newInstance();
Class.forName("P", true, MainClass.class.getClassLoader()).newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
---------- END SOURCE ----------