Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [platform-swt-dev] What is OS.JNIGetObject for in SWT Cococa?


You are using old code. The latest SWT code does not use tag/setTag() anymore. Check the code in HEAD. It subclasses the Cocoa widgets it needs and adds a instance var where the JNI refs are stored.

Silenio



"Andrey Tarantsov" <andreyvit@xxxxxxxxx>
Sent by: platform-swt-dev-bounces@xxxxxxxxxxx

10/10/2008 09:12 AM

Please respond to
"Eclipse Platform SWT component developers list."        <platform-swt-dev@xxxxxxxxxxx>

To
"Eclipse Platform SWT component developers list." <platform-swt-dev@xxxxxxxxxxx>
cc
Subject
Re: [platform-swt-dev] What is OS.JNIGetObject for in SWT Cococa?





Hi,

Regarding the tags, they are used to store a reference to a Java object that corresponds to a given Cocoa object. (Obviously you cannot pass a Java pointer into Cocoa, so we have to pass Java object references which are only available from JNI only, hence the JNI calls NewGlobalRef, DeleteGlobalRef and JNIGetObject. As far as I remember, the int -> Object mapping you're talking about is managed by the JVM itself, not by SWT.)

The Java object id is stored in a "tag" field of Cocoa objects, however there may be issues with this approach because Cocoa sometimes  wants to use the "tag" field for its own needs. Here's a letter my colleage Mikhail Kalugin has posted a few month ago to this mailing list:

Recently I met a weird problem with Display.getFocusControl() method:  
it was failing with NPE on "OS.JNIGetObject(tag);" call (line 1083).  
At first glance, this call doesn't do anything that can throw NPE.

After some investigations I've found the reason — tag wasn't an JNI  
object reference. It was a natively set tag by Cocoa itself. I was  
using NSAlert class which uses tags for the content view. So when my  
application was asking for a focus control, SWT was encountering  
NSAlert's window, asking for a tag in order to restore SWT's class and  
then failing.

Regarding concretely this issue, the solution is simple: the  
OS.JNIGetObject(tag); line can be surrounded by a try..catch block.

However, I think that problem has more deep roots. Really, why does  
SWT use tag()/setTag() methods for storing JNI refs? Since Cocoa can  
use tag field itself, it doesn't look as a secure solution. There are  
methods for creating/reading/updating instance variables in Cocoa  
object. So it would be possible to use some variable like  
"swt_jni_ref" to store refs.


He was recommended to open a bug to track it. I believe what you should do for your port is:


1) add a uniquely named field to your Cocoa objects instead of a generic "tag" field (e.g. "swt_tag");

2) instead of adding tag/setTag methods to each Cocoa object you define on SWT side, just read/write that "swt_tag" field directly using Objective-C runtime calls.

And yes, if D virtual machine does not readily map objects to integers (how does it handle native callbacks then?), you can manage the mapping yourself.

--
Andrey.
_______________________________________________
platform-swt-dev mailing list
platform-swt-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/platform-swt-dev


Back to the top