7

I'm trying to generate bytecode which will create object instance without code initialization logic. Actually I want to reproduce 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 such error:

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

1 Answer 1

10

JVM specification prohibits creation of objects without calling proper constructor. However, there are two tricky ways of doing this. Both of them are specific to OpenJDK / Oracle JDK and are not guaranteed to work on all Java implementations.

  1. Call sun.misc.Unsafe.allocateInstance() internal API to instantiate a class without calling a constructor.
  2. When generating a class in run-time, inherit your class from sun.reflect.MagicAccessorImpl. JVM will skip bytecode verification for such class thus allowing to have NEW bytecode without proper INVOKESPECIAL.

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.