JDK-6859079 : JNI_CreateJavaVM() terminates the process on error condition instead of returning error code
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 5.0,5.0u15,6
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic,windows_2003,windows_xp
  • CPU: generic,x86
  • Submitted: 2009-07-10
  • Updated: 2017-03-28
  • Resolved: 2017-03-28
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
JNI_CreateJavaVM() terminates the process after having encountered an 
error condition (e.g.: not enough memory), instead of returning an
appropriate error code (e.g.: -4)

from jni.h:
/*
 * possible return values for JNI functions.
 */

#define JNI_OK           0                 /* success */
#define JNI_ERR          (-1)              /* unknown error */
#define JNI_EDETACHED    (-2)              /* thread detached from the VM */
#define JNI_EVERSION     (-3)              /* JNI version error */
#define JNI_ENOMEM       (-4)              /* not enough memory */
#define JNI_EEXIST       (-5)              /* VM already created */
#define JNI_EINVAL       (-6)              /* invalid arguments */


The behavior is strictly reproducible and can be observed with
JDK 1.2.2, 1.3.1, 1.4.2, 1.5 and 1.6.

Here are 3 examples of the behavior:

1. Successful execution
-----------------------
JNI_CreateJavaVM() was successfully created: JNI_OK is returned:
Java program "HelloWorld" is executed.
Everthing is fine

% JNITest
JNI_CreateJavaVM returned 0
Hello World
%

2. Error condition encountered
------------------------------
JNI_CreateJavaVM() could not be created because of invalid memory
requirement: JNI_EINVAL is returned, and can be handled by the 
calling C program.
Everything is fine.

% JNITest
Invalid initial heap size: -Xms4096m
The specified size exceeds the maximum representable size.
JNI_CreateJavaVM returned -6
%

3. Error condition on insufficient memory
-----------------------------------------
JNI_CreateJavaVM() could not be created because of insufficient 
memory available: no error code is returned; the process is 
immediately terminated.
This is what the complaint is about.

% ./JNITest
Error occurred during initialization of VM
Could not reserve enough space for object heap
%


Here is what the docs say
-------------------------
 According to the docs, JNI_CreateJavaVM() "returns a negative number on failure."

 http://java.sun.com/j2se/1.4.2/docs/guide/jni/spec/invocation.html#wp16334 
 --------------------------------------------------------------------
 JNI_CreateJavaVM

 jint JNI_CreateJavaVM(JavaVM **p_vm, JNIEnv **p_env, void *vm_args);

 Loads and initializes a Java VM. The current thread becomes the main
 thread. Sets the env argument to the JNI interface pointer of the main
 thread.

 JDK 1.1 does not support creating more than one VM in a single process.
 The version field in vm_args must2 be set to 0x00010001.

 PARAMETERS:
[ ... ]

 RETURNS:
 Returns "0" on success; returns a negative number on failure.
 --------------------------------------------------------------------

Comments
Not a priority, closing as WNF.
28-03-2017

Added a bunch of new watchers for this bug. Feel free to reassign it to yourself. It's actually a bug not an ER but longstanding.
04-04-2013

NMT doesn't really help this. There are some allocations with malloc before the big Java heap mmap call. If we created a global initial arena, we could direct allocations during startup to this arena, assuming that they'd never be freed until the VM is exited. If we did that, we could deallocate the arena and return JNI_ENOMEM if we fail to allocate the Java heap. Using global new during initialization is also a problem but this is being addressed with bug https://jbs.oracle.com/bugs/browse/JDK-8010992.
04-04-2013

EVALUATION This is a project to address this error during startup, not a bug.
28-02-2012

EVALUATION We are using this bug to track not being able to recover from a failure to allocate enough memory for the Java heap (and some associated heap areas) during initialization. In this case, it makes sense to return an error code because the java heap is a large allocation in one place, early in the initialization of the VM. The problem with this is that the VM does other native heap allocations that we haven't tracked so if you return on failure these allocations will be leaked. One of our ongoing projects is native heap memory tracking. With this work, we will have a way of recovering the memory that is allocated during initialization. Therefore, the fix to this bug is deferred to JDK 8 or until this other work is done. See also : 6995781 Coleen
17-11-2010

EVALUATION The submitter is correct. Only a few errors during early VM initialization are reported as actual JNI errors. The majority of errors during VM initialization are fatal to the VM but the places where they are encountered do not have the means to propogate an error condition all the way back to the create_vm call, and the response of the VM to a fatal error is to abort the process. While some initialization errors might be modified to report JNI errors instead, in general it is not feasible to change these error paths. But for the particular case of heap initialization it might be feasible to make a change. (I'm sure there are already existing RFEs in this area.) If the VM is successfully loaded by a process, then the VM might later encounter a fatal error - such as C heap exhaustion - that will again terminate the host process. Native applications that wish to load a JVM need to be aware of the limitations in doing so.
10-07-2009