/** * Adds the instrumentation to deal with re-iniatilizing classes: adding * __STATIC_RESET() methods, inserting callbacks for PUTSTATIC and GETSTATIC * instructions * * @param className * @param cv * @return */ private static ClassVisitor handleStaticReset(String className, ClassVisitor cv) { // Create a __STATIC_RESET() cloning the original <clinit> method or // create one by default final CreateClassResetClassAdapter resetClassAdapter; if (Properties.RESET_STATIC_FINAL_FIELDS) { resetClassAdapter= new CreateClassResetClassAdapter(cv, className, true); } else { resetClassAdapter= new CreateClassResetClassAdapter(cv, className, false); } cv = resetClassAdapter; // Adds a callback before leaving the <clinit> method EndOfClassInitializerVisitor exitClassInitAdapter = new EndOfClassInitializerVisitor(cv, className); cv = exitClassInitAdapter; return cv; }
@Deprecated // This method is a code clone from MethodCallReplacementClassAdapter private void createSerialisableUID() { // Only add this for serialisable classes if (serialUID < 0) return; /* * If the class is serializable, then adding a hashCode will change the * serialVersionUID if it is not defined in the class. Hence, if it is * not defined, we have to define it to avoid problems in serialising * the class. */ logger.info("Adding serialId to class " + className); visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "serialVersionUID", "J", null, serialUID); }
/** {@inheritDoc} */ @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { if (name.equals("serialVersionUID")) { definesUid = true; // We must not remove final from serialVersionUID or else the // class cannot be serialised and de-serialised any more return super.visitField(access, name, desc, signature, value); } if (hasStaticModifier(access)) { StaticField staticField = new StaticField(); staticField.name = name; staticField.desc = desc; staticField.value = value; static_fields.add(staticField); } if (!isEnum && !isInterface && removeFinalModifierOnStaticFields) { int newAccess = access & (~Opcodes.ACC_FINAL); if (newAccess != access) { // this means that the field was modified modifiedStaticFields.add(name); } return super.visitField(newAccess, name, desc, signature, value); } else { if (hasFinalModifier(access)) finalFields.add(name); return super.visitField(access, name, desc, signature, value); } }
/** * After all the class code was visited, If no <clinit> was found, an empty * __STATIC_RESET() method is synthesized. */ @Override public void visitEnd() { if (!clinitFound && !isInterface && !isAnonymous && !resetMethodAdded) { // create brand new __STATIC_RESET if (!definesUid) { // determineSerialisableUID(); // createSerialisableUID(); } createEmptyStaticReset(); } else if (clinitFound) { if (!definesUid) { // createSerialisableUID(); } } if (!modifiedStaticFields.isEmpty()) { ModifiedTargetStaticFields.getInstance().addFinalFields(modifiedStaticFields); } super.visitEnd(); }
resetClassAdapter= new CreateClassResetClassAdapter(cv, className,true); } else { resetClassAdapter= new CreateClassResetClassAdapter(cv, className,false);
CreateClassResetClassAdapter resetClassAdapter = new CreateClassResetClassAdapter(cv, className, true); cv = resetClassAdapter;