Skip to content

Commit

Permalink
Merge pull request #646 from Thrameos/weak_proxy
Browse files Browse the repository at this point in the history
Weak proxy
  • Loading branch information
marscher committed Mar 31, 2020
2 parents 86faece + 38c3862 commit 715ad94
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 9 deletions.
7 changes: 6 additions & 1 deletion doc/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,12 @@ This changelog *only* contains changes from the *first* pypi release (0.5.4.3) o
for complience when accessing ``java.util.List`` elements.

- java.lang.NullPointerException can be caught with ValueError
for consistency with Python exception usage..
for consistency with Python exception usage.

- JProxy only creates one copy of the invocation handler per
garbage collection rather than once per use. Thus proxy objects
placed in memory containers will have the same object id so long
as Java holds on to it.

- **0.7.1 - 12-16-2019**

Expand Down
3 changes: 3 additions & 0 deletions native/common/include/jp_javaframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class JPJavaFrame
*/
void DeleteLocalRef(jobject obj);

jweak NewWeakGlobalRef(jobject obj);
void DeleteWeakGlobalRef(jweak obj);

JNIEnv* getEnv() const
{
return m_Env;
Expand Down
1 change: 1 addition & 0 deletions native/common/include/jp_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class JPProxy
PyObject* m_Instance; // This is a PyJPProxy
JPObjectRef m_Proxy;
JPClassList m_InterfaceClasses;
jweak m_Ref;
} ;

/** Special wrapper for round trip returns
Expand Down
16 changes: 13 additions & 3 deletions native/common/jp_javaframe.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*****************************************************************************
Copyright 2004-2008 Steve ©nard
Copyright 2004-2008 Steve Ménard
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -116,12 +116,22 @@ JPJavaFrame::~JPJavaFrame()

void JPJavaFrame::DeleteLocalRef(jobject obj)
{
m_Env->functions->DeleteLocalRef(m_Env, obj);
m_Env->DeleteLocalRef(obj);
}

void JPJavaFrame::DeleteGlobalRef(jobject obj)
{
m_Env->functions->DeleteGlobalRef(m_Env, obj);
m_Env->DeleteGlobalRef(obj);
}

jweak JPJavaFrame::NewWeakGlobalRef(jobject obj)
{
return m_Env->NewWeakGlobalRef(obj);
}

void JPJavaFrame::DeleteWeakGlobalRef(jweak obj)
{
return m_Env->DeleteWeakGlobalRef(obj);
}

jobject JPJavaFrame::NewLocalRef(jobject a0)
Expand Down
31 changes: 26 additions & 5 deletions native/common/jp_proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,23 @@ JPProxy::JPProxy(JPProxyFactory* factory, PyObject* inst, JPClassList& intf)
jobject proxy = frame.CallStaticObjectMethodA(m_Factory->m_ProxyClass.get(),
m_Factory->m_NewProxyID, v);
m_Proxy = JPObjectRef(m_Factory->m_Context, proxy);
m_Ref = NULL;
JP_TRACE_OUT;
}

JPProxy::~JPProxy()
{
try
{
JPContext *context = getContext();
if (m_Ref != NULL && context->isRunning())
{
context->getEnv()->DeleteWeakGlobalRef(m_Ref);
}
} catch (JPypeException &ex)
{
// Cannot throw
}
}

jvalue JPProxy::getProxy()
Expand All @@ -229,12 +241,21 @@ jvalue JPProxy::getProxy()
JPContext* context = getContext();
JPJavaFrame frame(context);

// Use the proxy to make an instance
JP_TRACE("Create handler");
Py_INCREF(m_Instance);
jobject instance = frame.CallObjectMethodA(m_Proxy.get(),
m_Factory->m_NewInstanceID, 0);
jobject instance = NULL;
if (m_Ref != NULL)
{
instance = frame.NewLocalRef(m_Ref);
}

if (instance == NULL)
{
// Use the proxy to make an instance
JP_TRACE("Create handler");
Py_INCREF(m_Instance);
instance = frame.CallObjectMethodA(m_Proxy.get(),
m_Factory->m_NewInstanceID, 0);
m_Ref = frame.NewWeakGlobalRef(instance);
}
jvalue out;
out.l = frame.keep(instance);
return out;
Expand Down
16 changes: 16 additions & 0 deletions test/jpypetest/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,3 +443,19 @@ class R(object):
self.assertIsInstance(s.getClass(), java.lang.Class)
self.assertIsInstance(s.toString(), java.lang.String)
self.assertIsInstance(s.hashCode(), int)

def testWeak(self):
hc = java.lang.System.identityHashCode
@JImplements("java.io.Serializable")
class MyObj(object):
pass
def f():
obj = MyObj()
jobj = JObject(obj)
i = hc(obj)
return i, obj
i0, obj = f()
i1 = hc(obj)
# These should be the same if unless the reference was broken
self.assertEqual(i0, i1)

0 comments on commit 715ad94

Please sign in to comment.