Strange Issue With Static Global Variable in Native
Chris Hegarty
chris.hegarty at oracle.com
Mon Dec 9 02:09:52 PST 2013
On 08/12/13 17:39, Dan Xu wrote:
>
> On 12/08/2013 01:34 AM, Chris Hegarty wrote:
>>
>> On 07/12/2013 18:12, Dan Xu wrote:
>>> ...
>>>> Just so I understand, did you use a JNI global when caching the
>>>> reference?
>>>>
>>>> -Alan
>>> Hi Alan,
>>>
>>> What is a JNI global?
>>
>> http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp1242
>>
>>
>> > What I use here is a static global variable. I
>>> have uploaded this file to
>>> http://cr.openjdk.java.net/~dxu/8025437/DefaultProxySelector1.c. You can
>>> search for "no_proxy". I have declared this variable as "static jobject'
>>> at the beginning, and initialized it in function initJavaClass().
>>
>> You can only store global, not local, refs across multiple
>> calls/contexts.
>>
>> In your case it would look something like:
>>
>> static jobject setNoProxy(JNIEnv *env) {
>> jobject empty_proxy = NULL;
>> jfieldID pr_no_proxyID = NULL;
>> pr_no_proxyID = (*env)->GetStaticFieldID(env,
>> proxy_class,
>> "NO_PROXY", "Ljava/net/Proxy;");
>> if (proxy_class && pr_no_proxyID) {
>> printf("create NO_PROXY\n");
>> empty_proxy = (*env)->GetStaticObjectField(env,
>> proxy_class, pr_no_proxyID);
>>
>> empty_proxy = (*env)->NewGlobalRef(env, empty_proxy);
>> }
>> return empty_proxy;
>> }
>>
>> -Chris.
>
> Do you mean (*env)->GetStaticObjectField() return me a local reference?
Yes. Quote from the spec, "All Java objects returned by JNI functions
are local references. "
> When shall I call NewGlobalRef()?
I included the NewGlobalRef call in the code above (a modified version
of setNoProxy). Directly after GetStaticObjectField.
In Proxy.java, this static field has
> already been created by "public final static Proxy NO_PROXY = new
> Proxy();" And I still need call NewGlobalRef() to make it global, right?
Yes. You are adding a new reference to this object, from JNI code. This
reference needs to be registered with the GC so it can be updated if the
referent is relocated.
> But why is it not necessary for me to call NewGlobalRef() for
> ptype_httpID and ptype_socksID? Thanks!
These are not reference to Java Objects, they are of type jmethodID. You
can think of them as pointers/offsets into particular type, and are not
subject to change.
-Chris.
>
> -Dan
More information about the net-dev
mailing list