Creating an instance of an object without calling the initializer

I am trying to create bytecode that will instantiate an object without code initialization logic. In fact, I want to reproduce the generateSerializationConstructor behavior.

{ mv = cw.visitMethod(ACC_PUBLIC, "newObjectInstance", "()Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, classNameInternal); mv.visitInsn(DUP); classNameInternal = "java/lang/Object"; mv.visitMethodInsn(INVOKESPECIAL, classNameInternal, "<init>", "()V"); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } 

Unfortunately, I got this error:

java.lang.VerifyError: (class: com / esotericsoftware / reflectasm / benchmark / ConstructorAccessBenchmark $ SomeClass_ClassAccess_, method: newObjectInstance signature :() Ljava / lang / Object;) Calling the wrong initialization method

+6
source share
1 answer

The JVM specification prohibits the creation of objects without calling the appropriate constructor. However, there are two difficult ways to do this. Both are specific to OpenJDK / Oracle JDK and do not guarantee work on all Java implementations.

  • Call sun.misc.Unsafe.allocateInstance () the internal API to instantiate the class without calling the constructor.
  • When creating a class at runtime, inherit your class from sun.reflect.MagicAccessorImpl. The JVM will skip bytecode validation for this class, which will allow a NEW bytecode without proper INVOKESPECIAL.

Both methods are used in our custom serialization engine, which can be found at https://github.com/odnoklassniki/one-nio/blob/master/src/one/nio/serial/

+8
source

All Articles