JNI - Object creation with incorrect constructor

Piotr Chmielewski piotr.ch.dev at gmail.com
Fri Mar 10 16:41:42 UTC 2017


Thanks for answer.

To clarify:

1. Is it up to programmer to ensure correctness of type/constructor 
match as there no checks to detect mismatch (I did not find any in 
documentation) ?

2. In presented example, was object actually partially constructed 
because of my error and how Hotspot handled it ?


On 10.03.2017 16:55, Roger Riggs wrote:
> Hi Piotr,
>
> Using JNI requires a quite a bit more care than the Java API, there 
> are fewer checks
> and guarantees.  Make sure you are calling the method/constructor you 
> intend to.
> What you are seeing is an artifact of JNI and the Hotspot implementation.
> Double check all JNI code twice before using.
>
> $.02, Roger
>
>
> On 3/10/17 10: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 ?
>>
>



More information about the jdk9-dev mailing list