[Info-vax] JNI problem on I64

Arne Vajhøj arne at vajhoej.dk
Sat Jan 29 19:38:00 EST 2022


On 1/26/2022 8:50 AM, Simon Clubley wrote:
> On 2022-01-25, Arne Vajhøj <arne at vajhoej.dk> wrote:
>> Code outline:
>>
>> ... (JNIEnv *cntx, jobject baobj)
>> ...
>> signed char *buf;
>> ...
>> buf = (*cntx)->GetByteArrayElements(cntx, baobj, NULL);
>> ...
>> ...
>> ...
>> (*cntx)->ReleaseByteArrayElements(cntx, baobj, buf, 0);
>>
>> VMS Alpha 8.4 with Java 1.5 : works fine
>>
> 
> _Appears_ to work fine. :-)

It passes an extensive test suite.

But producing the desired results with no visible side
effects does not mean that the code is correct on that
platform, just that it can't be debugged there.

There is a 99.9% probability that there is a bug in my
code. I just need to find it.

>> VMS I64 8.4 with Java 8 : crashes (the output is attached below)
>>
>> ReleaseByteArrayElements calls memcpy and memcpy calls something
>> in LIBOTS that does an access violation.
>>
>> I understand the memcpy - if GetByteArrayElements returned a copy
>> of the JVM data then ReleaseByteArrayElements has to copy the modified
>> data back.
>>
>> But neither baobj nor buf has changed. So I am totally baffled
>> over why I can get  an access violation.
>>
>> Does anyone have an idea about what I should be looking for?
> 
> Any behaviour change if you compile in debug mode or change optimisation
> levels (including turning off all optimisation) ?

I have not tried.

It is typical not something that matters on VMS.

But easy to try.

> If you compile in debug mode, does looking at your variables reveal
> anything interesting ? For example, can you look at the expected end
> of the returned buffer in the debugger without getting an access violation ?

Pointers are valid.

I can printf both pointers and what they point at.

> Is there just the one thread running in your code ?

In my code both Java and C: yes.

But JVM probably has a few housekeeping threads around. The JVM
could easily run GC, but it should not be able to GC or move
the variables the C Code is using.

> You could also return the isCopy field in your call to see if a copy
> is actually being made instead of just assuming it is.

I could.

But I really don't care why ReleaseByteArrayElements does
a memcpy. I am pretty sure that it is because I got a copy,
but if that is not a case in it does memcpy for some other
reason, then I am not really the wiser.

> Also, is "signed char *buf" the same as declaring it using the correct
> JNI supplied data type ?

typedef signed char jbyte;

> PS: BTW, some would say that the JNI design _is_ the problem. :-)
> 
> PPS: Spoken as someone who has now played with this stuff on Android. :-)

The JNI API is very low level and rather cumbersome.

It was designed in the context of mid 90's with strong efficiency
requirements and lots of available C skill and for obvious reasons
little Java skill available.

The replacement is getting ready.

The foreign function API was made preview in Java 16 and I *hope*
that it will become standard in 19 or 20.

Arne





More information about the Info-vax mailing list