1 Reply Latest reply: Jun 9, 2009 5:03 AM by 843829 RSS

    NullPointerException on JVM startup when changing Class.getDeclaredField()

      On any JVM starting with 1.5 and later the included test case causes this exception on startup:
      at java.util.Hashtable.put(Hashtable.java:394)
      at java.lang.System.initProperties(Native Method)
      at java.lang.System.initializeSystemClass(System.java:1072)

      The test case involves overriding Class.getDeclaredField() via -Xbootclasspath/p. Originally the bug came out when using Instrumentation.redefineClasses().

      To run the test case:
      1) Download and unzip from [http://ngra.de/gdm-test.zip]
      2) Run "java -cp asm-all-3.1.jar:gdm.jar Install", this will generate a gdm-boot.jar file.
      3) Run "java -Xbootclasspath/p:gdm.jar:gdm-boot.jar Test", this should produce the error.

      The test cases adds one method call before ARETURN instruction in Class. getDeclaredField(). The call is INVOKESTATIC Test.test()V.

      Does anyone know if it's a known bug and if there are any workarounds for this? The same bug manifests in Instrumentation.redefineClasses() by messing up the constant pool when the getDeclaredField() is changed
        • 1. Re: NullPointerException on JVM startup when changing Class.getDeclaredFiel
          Apparently the problem was that in Java 5+ there is a AtomicReferenceFieldUpdaterImpl, which is accessed from System.initializeClass() on JVM startup and which calls Class.getDeclaredField(). Since at that point the proper classloading is not set up yet, trying to access a class outside rt.jar causes a ClassNoDefFoundError cascading upwards to the NPE we get. The fix is to check the sun.misc.VM.isBooted() flag to be sure that class loading is allowed, otherwise skipping the injected code. Hope this can help someone :)