CSR :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
There is a discrepancy between the behaviour of Java 9 and the jvmti spec (http://cr.openjdk.java.net/~mr/jigsaw/spec/jvmti.html#RedefineClasses) The spec states: "The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance." However, RI allows private methods and inner classes to be added without throwing JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED. There is the transform method: @Override public byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (className.equals("p/C")) { transformModule(module); byte[] retransformedClazz1Bytes = new LocalDirClassLoader("Instrumentation.redefine_after", null).loadClassData("p/C.class"); } else { return null; } } that substitutes the class p/C ---------------------------------------------------------------- package p; public class C { public static boolean checkReads() { return false; } public static boolean checkUses() { return false; } public static boolean checkProvides() { return false; } } ---------------------------------------------------------------- with the class p/C ---------------------------------------------------------------- package p; import p3.E; import java.util.ServiceLoader; public class C { public static boolean checkReads() { return E.getOne() == 1; } public static boolean checkUses() { return ServiceLoader.load(C.class.getModule().getLayer(), ServiceOne.class) .findFirst() .map(s -> s instanceof ServiceOneImpl) .orElse(false); } public static boolean checkProvides() { return ServiceLoader.load(C.class.getModule().getLayer(), ServiceTwo.class) .findFirst() .map(s -> s instanceof ServiceTwoImpl) .orElse(false); } } ---------------------------------------------------------------- This retransformation is allowed by RI, although it contradicts the specification above because the transformed class contains extra public static final InnerClass Lookup and methods: private static synthetic Method lambda$checkProvides$1:"(Lp/ServiceTwo;)Ljava/lang/Boolean;" private static synthetic Method lambda$checkUses$0:"(Lp/ServiceOne;)Ljava/lang/Boolean;" The specification should be weakened according to accessibility of methods and/or fields(?).
|