JNI - Object creation with incorrect constructor

Piotr Chmielewski piotr.ch.dev at gmail.com
Sun Mar 12 23:34:31 UTC 2017


Thanks for response, both Roger and David :)

I imagine, it doesn't change anything when calling these function not 
from Java method marked with "native" keyword but from C/C++ when 
starting VM using Invocation API ?


On 11.03.2017 05:06, David Holmes wrote:
> Hi Piotr,
>
> On 11/03/2017 1:23 AM, Piotr Chmielewski wrote:
>> When working on code with JNI Invocation API, I stumbled upon curious 
>> case.
>>
>> Following code describes use of incorrect constructor in type when
>> creating new object.
>>
>>
>> JNIEnv* env = ...;
>>
>> jclass cls_Object = env->FindClass("java/lang/Object");
>> jmethodID constructor_Object = 
>> env->GetMethodID(cls_Object,"<init>","()V");
>> jclass cls_Date = env->FindClass("java/util/Date");
>> jmethodID method_Date_toString =
>> env->GetMethodID(cls_Date,"toString","()Ljava/lang/String;");
>>
>> jobject obj_Date = env->NewObject(cls_Date,constructor_Object);
>> jobject obj_toString =
>> env->CallObjectMethod(obj_Date,method_Date_toString);
>>
>> jstring str = static_cast<jstring>(obj_toString);
>> jsize length = env->GetStringLength(str);
>> char* dateString = new char[length];
>> jsize start = 0;
>> env->GetStringUTFRegion(jvmStr,start,length,data);
>> std::cout << "Date: " << dateString << std::endl;
>> delete[] dateString;
>>
>>
>> This code works and prints "Thu Jan 01 01:00:00 CET 1970".
>>
>> Looks like "valid?" Date object is created using Object constructor -
>> partially created object.
>>
>> To understand the behavior, I checked OpenJDK sources for HotSpot.
>> Implementation of "NewObject" allocates space for object and executes
>> method on allocated space.
>>
>> Additionally, based on sources of "java.util.Date", memory for object
>> "obj_Date" is allocated and its values are set to default values. Date
>> then uses field "long fastTime" in toString method. This results as
>> object was created with "new Date(0)" instead "new Date()";
>>
>> Main question: Is it a bug or by design, constructor's jmethodID is not
>> checked to belong to type when creating object ?
>
> By design. It is up the the programmer to use JNI correctly:
>
> http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html 
>
>
> "Reporting Programming Errors
>
> The JNI does not check for programming errors such as passing in NULL 
> pointers or illegal argument types. Illegal argument types includes 
> such things as using a normal Java object instead of a Java class 
> object. The JNI does not check for these programming errors for the 
> following reasons:
>
>     Forcing JNI functions to check for all possible error conditions 
> degrades the performance of normal (correct) native methods.
>     In many cases, there is not enough runtime type information to 
> perform such checking.
>
> Most C library functions do not guard against programming errors. The 
> printf() function, for example, usually causes a runtime error, rather 
> than returning an error code, when it receives an invalid address. 
> Forcing C library functions to check for all possible error conditions 
> would likely result in such checks to be duplicated--once in the user 
> code, and then again in the library.
>
> The programmer must not pass illegal pointers or arguments of the 
> wrong type to JNI functions. Doing so could result in arbitrary 
> consequences, including a corrupted system state or VM crash."
>
> ----
>
> Note the last sentence in particular. :)
>
> Cheers,
> David
>



More information about the jdk9-dev mailing list