JDK-8305104 : Remove the old core reflection implementation
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-03-28
  • Updated: 2023-07-12
  • Resolved: 2023-06-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 22
22 b02Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Sub Tasks
JDK-8309699 :  
Description
JEP 416 reimplemented the core reflection with method handles in JDK 18.   There has been only a couple minor issues reported since JDK 18 (issue with exception being thrown with invalid arguments).   It's time to remove the old core reflection implementation.
Comments
Changeset: 9bfe415f Author: Mandy Chung <mchung@openjdk.org> Date: 2023-06-13 19:41:38 +0000 URL: https://git.openjdk.org/jdk/commit/9bfe415f66cc169249d83fc161c9c4496fe239f6
13-06-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/14371 Date: 2023-06-07 21:29:34 +0000
07-06-2023

While it may be a good idea to reimplement `newConstructorForSerialization` with method handle, I'm not sure if we want to move this hack into method handle implementation to allocate an instance of one class but invoke a constructor of another class (its superclass). I'd give it more time to think through JDK-8307575. This issue will remove the old core reflection implementation. The VM hacks will remain until the serialization constructor accessor is replaced with something else like JDK-8307575.
01-06-2023

I think these custom constructors that allocate a class and invokes a superclass constructor can be covered by method handles as well: see JDK-8307575 where the allocation is done by DirectMethodHandle::allocateInstance and constructor invocation is linked by MethodHandle::linkToSpecial, as defined by its lambda form. This appears to be free from VM's verification process as well. In addition, the newConstructorForSerialization is a security issue like Unsafe; it allows breaking strong encapsulation as it allows calling any constructor, such as those of MethodHandles.Lookup. newConstructorForExternalization doesn't appear to depend on this custom allocation and constructor invocation mechanism.
24-05-2023

Summary of the VM hacks introduced by the old reflection implementation in JDK 1.4. There are several hacks introduced due to dynamic bytecode stubs approach for reflection to workaround the compatibility and security issues. - VM skips verification for these dynamic bytecode stubs for reflection (`jdk.internal.reflect.MagicAccessorImpl` classes) because the dynamic bytecode stub `C` in calling `Object.clone` reflectively would fail verification as `C` is a subclass of `Object` and `C` is not allowed to call `Object::clone` per JLS section 6.6.2 (see JDK-4486457) - Each dynamic bytecode stub class is defined by a new class loader (an instance of `jdk.internal.reflect.DelegatingClassLoader`) whose parent class loader is the defining loader of the target class such that these classes can be be unloaded early even if the target class and its defining loader is still reachable. However, the VM has the following special handling of `DelegatingClassLoader`: - The dynamic bytecode stubs exposed bugs in custom class loader implementations that native reflection implementation never runs into. For compatibility, VM has to workaround for the ill-behaved custom class loaders and bypass the normal class loader delegation implementation. Instead it magically delegates class loading to to its parent loader directly in the VM (see JDK-4474172 and JDK-6790209 for details) - Metaspace is allocated for class loaders which generally loads more than one class but each `DelegatingClassLoader` instance only loads one single class. To reduce the amount of unused space reserved, VM has to create a custom-sized metaspace of `ReflectionMetaspaceType` for these `DelegatingClassLoader` loaders. - jcmd has to specially inspect these dynamic bytecode stubs to help determine the specific metaspace usage for core reflection. - Deserialization relies on VM support (`JVM_LatestUserDefinedLoader`) to look up the latest user-defined loader. `JVM_LatestUserDefinedLoader` has to specially filter these dynamic bytecode stubs since they are defined by non built-in class loaders. JEP 416 does not change the implementation of `sun.reflect.ReflectionFactory::newConstructorForSerialization` and `sun.reflect.ReflectionFactory::newConstructorForExternalization`. It generates bytecode to fabricate a `Constructor` that instantiates the given class `C` and invoke a no-arg constructor of `C`'s first non-`Serializable` superclass `A`. Note that this is not a valid operation per the VM specification; `new C; invokespecial A()` gets a verification error. This implementation shares the same marker interface `ConstructorAccessorImpl` as core reflection such that the generated class will skip verification. When the dynamic bytecode stub implementation is removed, VM will skip verification for the constructors generated for serialization and externalization.
28-03-2023

> Does this include the old implementation for generating constructors for serialization? No and `sun.reflect.ReflectionFactory::newConstructorForSerialization` and `sun.reflect.ReflectionFactory::newConstructorForExternalization` continue to use the old reflection implementation. But the VM hacks will only be restricted for serialization constructor accessor.
28-03-2023

Does this include the old implementation for generating constructors for serialization? It was not migrated and still uses the old magic generator.
28-03-2023