Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2006

Tip: Looking for answers? Try searching our database.

Pedantic JNI question

Thread view: 
Bill Medland - 20 Oct 2006 00:20 GMT
I'm just trying to do the job properly and the correct answer is not obvious
to me in the documentation.

a-If I call GetByteArrayRegion I should later call ReleaseByteArrayRegion.
b-If an exception is thrown then the only functions that it is safe to call
are ExceptionCheck(I presume, but the docs don't say so), ExceptionClear,
ExceptionDescribe and ExceptionOccurred.

So does that mean in the event of an exception we can return safely without
bothering with the ReleaseByteArrayRegion calls (and the system will tidy
up).

Signature

Bill Medland

David Lee Lambert - 20 Oct 2006 02:51 GMT
> I'm just trying to do the job properly and the correct answer is not obvious
> to me in the documentation.
[quoted text clipped - 7 lines]
> bothering with the ReleaseByteArrayRegion calls (and the system will tidy
> up).

There is no ReleaseByteArrayRegion call in the JNI spec.  Did you mean
ReleaseByteArrayElements?

Anyway,  according to the way I read the spec, the statement that "When
there is a pending exception, the only JNI functions that are safe to call
are..." means just what it says.  In general the JVM cleans up dangling
references upon return from a native function.  It could be argued that
the native-type-array pointers returned by
Get<type>ArrayElements, GetStringChars and GetStringUTFChars are not local
references, so I always clean them up if possible;  but I'm not sure
exactly what different JVMs do.

If you want to do some cleanup that requires calls into the JVM,  you have
an alternative:  store the "jthrowable" returned by ExceptionOccurred
somewhere;  call ExceptionClear;  make your calls;  call Throw with the
"jthrowable" you stored before you return from the native function.  

Signature

PGP key posted on website ... http://www.lmert.com/people/davidl/

Bill Medland - 20 Oct 2006 20:31 GMT
>> I'm just trying to do the job properly and the correct answer is not
>> obvious to me in the documentation.
[quoted text clipped - 11 lines]
> There is no ReleaseByteArrayRegion call in the JNI spec.  Did you mean
> ReleaseByteArrayElements?

Woops, Yes - I meant Elements, not Region, of course.

> Anyway,  according to the way I read the spec, the statement that "When
> there is a pending exception, the only JNI functions that are safe to call
[quoted text clipped - 9 lines]
> somewhere;  call ExceptionClear;  make your calls;  call Throw with the
> "jthrowable" you stored before you return from the native function.

Thanks for your input, David.

I guess I'll just leave the "references" dangling around; I am not going to
start messing about putting exceptions away for a moment, unwinding,
reinstating  the exception, handling the possibility that reinstating the
exception fails, etc.
I'm sure they thought about it when they designed the system; I just wish
they'd documented their conclusions.
Signature

Bill Medland

Chris Uppal - 23 Oct 2006 09:43 GMT
> I guess I'll just leave the "references" dangling around; I am not going
> to start messing about putting exceptions away for a moment, unwinding,
> reinstating  the exception, handling the possibility that reinstating the
> exception fails, etc.
> I'm sure they thought about it when they designed the system; I just wish
> they'd documented their conclusions.

I think that's a very bad idea.  There is no reason at all (that I know of) to
suppose that it is intended to be safe to leave those "byte-array-regions"
unreleased.  The documentation, as you've noted, contains no hint that that is
allowed.  Also, I can see no sensible reason why the JNI people would put time
and effort into automatic reclaimation of byte-array-regions which only worked
in the error case -- I can just about imagine them wanting[*] to arrange for
automatic reclaimation (similar to reclaiming local references), but if so then
it would surely work in the main-line case, not just the exceptional one.

   -- chris

[*] I can imagine them wanting to arrange that, but I find it a lot harder to
imagine a practical implementation.
Bill Medland - 23 Oct 2006 15:17 GMT
>> I guess I'll just leave the "references" dangling around; I am not going
>> to start messing about putting exceptions away for a moment, unwinding,
[quoted text clipped - 7 lines]
> "byte-array-regions"
> unreleased.

"because we thought of that and it won't be a problem; we can define a good
api that won't make the programmer jump through hoops just to write robust
code; after all, we are professional programmers and we would want to write
robust code so lets assume the users of our api will too"

> The documentation, as you've noted, contains no hint that
> that is
[quoted text clipped - 4 lines]
> references), but if so then it would surely work in the main-line case,
> not just the exceptional one.

Ah well, whoever said life was easy.  I suppose I'll have to bite on the
bullet.  No wonder there is a tendency not to look at the return code and
simply do what seems to work often enough.

>     -- chris
>
> [*] I can imagine them wanting to arrange that, but I find it a lot harder
> [to
> imagine a practical implementation.

Signature

Bill Medland

Chris Uppal - 23 Oct 2006 16:06 GMT
[me:]
> >  There is no reason at all (that I know
> > of) to suppose that it is intended to be safe to leave those
[quoted text clipped - 5 lines]
> robust code; after all, we are professional programmers and we would want
> to write robust code so lets assume the users of our api will too"

<grin/>

I think Sun's position is that if you want that kind of thing then you should
be using Java, not C ;-)

   -- chris
Bill Medland - 23 Oct 2006 16:57 GMT
> [me:]
>> >  There is no reason at all (that I know
[quoted text clipped - 13 lines]
>
>     -- chris
Yeh.  Anyway, thanks for the reality check, Chris.
Signature

Bill Medland

Bill Medland - 23 Oct 2006 19:32 GMT
>>> I'm just trying to do the job properly and the correct answer is not
>>> obvious to me in the documentation.
[quoted text clipped - 39 lines]
> I'm sure they thought about it when they designed the system; I just wish
> they'd documented their conclusions.

Latest news.  They(/he) did.  So that just muddies the water even further.
In Sheng Liang's "Programmer's Guide and Specification" his section 11.8.2
lists a much larger selection of functions that are safe to call while
there is an exception pending, including Release<Type>ArrayElements.

So who do you believe?  The author of the design or the documentation that
comes with the product.

Seeing as Sheng Liang actually includes ExceptionCheck in his list, which
the documentation doesn't, and seeing as how I am less than impressed with
Sun's quality on some other things I think it is actually more reasonable
to go with his specification than the one that comes with the Sun Java
product (what a thing to have to say!).

So I am going to assume that it is safe to call
Release<Type>ArrayElements(...JNI_ABORT) with there being an exception
current and that it will not overwrite the exception.
Signature

Bill Medland

Chris Uppal - 24 Oct 2006 12:23 GMT
> Latest news.  They(/he) did.  So that just muddies the water even further.
> In Sheng Liang's "Programmer's Guide and Specification" his section 11.8.2
> lists a much larger selection of functions that are safe to call while
> there is an exception pending, including Release<Type>ArrayElements.

Ah! Good.

> So who do you believe?  The author of the design or the documentation that
> comes with the product.

I would believe whichever seemed most plausible ;-)

I'd prefer to believe the spec, and certainly I would take the spec over Liang
if there was a chance that Liang was simplifying (or even being mildly
inaccurate) for the sake of exposition.  But in a case like this where they
flat-out contradict each other, and where the spec is obviously
wrong/incomplete anyway (missing ExceptionCheck(), as you say), I would take
Liang.  After all Liang's stuff was written after, and presumably in full
knowledge of, the spec.

BTW, I found the thing about it being improper to DeleteLocalRef() with the
wrong JNIEnv.  It wasn't quite what or where I remembered it (though it has the
same effect on my code).  In /Liang's/ version of the spec, the second
paragraph of the text for that function states

   Deleting a local reference that does not belong to the topmost
   local reference frame is a no-op. Each native method invocation
   creates a new local reference frame. The PushLocalFrame
   function (added in Java 2 SDK release 1.2) also creates a new
   local reference frame.

So it isn't actually an /error/ as such, although it doesn't do what one might
expect.  There is (irritatingly) no equivalent to that paragraph in the version
of the JNI spec which comes with JDK 1.4 or 1.5...

   -- chris
Bill Medland - 24 Oct 2006 18:28 GMT
> BTW, I found the thing about it being improper to DeleteLocalRef() with
> the
[quoted text clipped - 15 lines]
>
>     -- chris
Well that was a little brain-dead, wasn't it :-)
So that means if I have a library function that carefully deletes all the
local references it creates I still have to keep track of how many
references there were because if Push/PopLocalFrame is called it needs to
allow for all those references that won't actually be deleted after all.
(What's the smiley for "shakes head in total resignation?")

Signature

Bill Medland

Chris Uppal - 26 Oct 2006 11:28 GMT
> Well that was a little brain-dead, wasn't it :-)
> So that means if I have a library function that carefully deletes all the
> local references it creates I still have to keep track of how many
> references there were because if Push/PopLocalFrame is called it needs to
> allow for all those references that won't actually be deleted after all.

That is why my stuff (if run in a mode where there can possibly be more than
one JNIEnv/local frame active) now converts /all/ local references to globals
as soon as it sees them, and at the lowest level of the housekeeping code.  I
tried a few more "clever" approaches (stacks of JNIEnvs and so on) before
deciding they were all too difficult to make right, and fell back to good old
brute force.

Not very nice, really...

   -- chris


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.