JDK-8273302 : Clarify the specification of JNI DestroyJavaVM in relation to "unloading the VM"
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 18
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2021-09-02
  • Updated: 2022-07-31
  • Resolved: 2021-10-09
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 18
18 b19Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The specification for JNI's DestroyJavaVM starts with:

"Unloads a Java VM and reclaims its resources."

but then ends with:

"Unloading of the VM is not supported."

which is a direct contradiction and leaves it very unclear what DestroyJavaVM actually does.

The original JNI programmers book (which was the precursor to the spec document) states the following:

The support for DestroyJavaVM was not complete in JDK
release 1.1; only the main thread may call DestroyJavaVM. The
virtual machine implementation blocks until the main thread is
the only user-level thread and returns a negative error code.

Java 2 SDK release 1.2 still does not support unloading virtual
machine instances. There is a slight relaxation to the use of
DestroyJavaVM, however; any thread may call DestroyJavaVM.
The virtual machine implementation blocks until the current
thread is the only user thread before it returns an error code.

---

I think the final sentence in the spec is what is left of that block of text. Obviously we improved things to the point where it does actually "terminate" the VM by some definition and returns JNI_OK rather than an error code. But it remains true that the VM is not actually unloaded from the process, and only some resources are reclaimed. The specification needs to be updated to clarify this.
Comments
After much discussion in relation to the CSR request it has been decided to update the specification as follows: -Unloads a Java VM and reclaims its resources. +Terminates the operation of the JVM, making a best-effort attempt to release resources. references to "unloading" are replaced by "terminating". This loosens the specification such that the Hotspot implementation is now consistent with it, whilst still allowing other implementations to continue to do what they do.
08-10-2021

Summary: When the JNI Invocation API was designed, the intent was to provide a means to load and unload a JVM within a hosting process. This met with numerous technical difficulties and the specification updated to indicate that unloading was not supported in 1.1 but you could still call DestroyJavaVM under specific conditions and it would return JNI_ERR. In JDK 1.2 these conditions were relaxed a little but still "unloading" was not supported. The specification document underwent few changes from that point, until the historical text was removed in 2013 (JDK 8?) and some minor (incomplete) changes made to the wording (JDK-6701692). This resulted in the contradictory wording as observed today, that DestroyJavaVM "Unloads a Java VM and reclaims its resources." yet "Unloading of the VM is not supported.". Meanwhile the implementation in hotspot evolved to provide the VM shutdown semantics that we observe today, where various shutdown protocols are observed at the Java level (ShutdownHooks), and within the VM (bring the VM to a safepoint and terminate some internal threads), but we still cannot "unload" the JVM from a process. This implementation supports the definition of "Program Exit"(JLS 12.8), using the DestroyJavaVM API as the mechanism to wait for the last non-daemon user thread to exit; and following the shutdown protocol defined under java.lang.Runtime::addShutdownHook. It is unclear what should be done to the specification document to more clearly express this reality. It would be wrong, in my opinion, to actually change the specification to reflect what Hotspot does, and does not do - other implementations should be free to implement VM unloading if they can manage it. But the specification is also not, generally, the place to document Hotspot limitations (hence the removal of the historical notes in the past). In terms of compliance it is arguably a quality of implementation issue that the VM is not actually "unloaded" and there are no APIs available to write any kinds of tests for the VM being "unloaded". But we have an existing contradiction that should be fixed, and it seems to me that the orphan statement: "Unloading of the VM is not supported." should actually be an "Implementation note" that could be expanded to read: Implementation Note: Unloading of the VM from a hosting process is not supported in the Hotspot implementation, but DestroyJavaVM will "shutdown" the VM's operation, following the definition of "Program Exit" in JLS 12.8 and the shutdown protocol defined by java.lang.Runtime::addShutdownHook.
20-09-2021

See JDK-6179880 for a summary of later attempts to expand on the shutdown behaviour. JDK-6283297 seems to be a recent update to the specification in this area. But the actual change is unclear. JDK-6701692 effectively is a duplicate of this issue. But the resolution there was to remove the final line that stated that the VM does not support unloading! However it only did that from the descriptive section of the invocation API within the spec, not from the actual definition of the DestroyJavaVM function. The removal of the historical text concerning JDK 1.1 and 1.2 was done as part of a general "cleanup" in 2013 (JDK 8?) but with no associated JBS issue.
03-09-2021