Skip to content
Permalink
Browse files

Hardening patch for detached threads and shutdown.

  • Loading branch information...
Thrameos committed Jun 3, 2018
1 parent 3cf0915 commit df4ba2312f4ea7800d8e0d700cd08fbc3ffc07e5
Showing with 6,539 additions and 7,314 deletions.
  1. +7 −0 doc/CHANGELOG.rst
  2. +0 −1 jpype/_core.py
  3. +0 −2 jpype/_jpackage.py
  4. +0 −2 jpype/_refdaemon.py
  5. +1 −1 jpype/imports.py
  6. +9 −7 jpype/reflect.py
  7. +68 −0 native/common/include/jp_booleantype.h
  8. +74 −0 native/common/include/jp_bytetype.h
  9. +72 −0 native/common/include/jp_chartype.h
  10. +3 −3 native/common/include/jp_classbase.h
  11. +67 −0 native/common/include/jp_doubletype.h
  12. +19 −51 native/common/include/jp_env.h
  13. +132 −0 native/common/include/jp_exception.h
  14. +68 −0 native/common/include/jp_floattype.h
  15. +70 −0 native/common/include/jp_inttype.h
  16. +0 −160 native/common/include/jp_javaenv.h
  17. +0 −468 native/common/include/jp_javaenv_autogen.h
  18. +353 −0 native/common/include/jp_javaframe.h
  19. +40 −23 native/common/include/{jp_invocationhandler.h → jp_jcharstring.h}
  20. +7 −11 native/common/include/jp_jniutil.h
  21. +69 −0 native/common/include/jp_longtype.h
  22. +1 −5 native/common/include/jp_method.h
  23. +1 −1 native/common/include/jp_methodoverload.h
  24. +14 −14 native/common/include/jp_objecttypes.h
  25. +166 −0 native/common/include/jp_primitive_common.h
  26. +62 −0 native/common/include/jp_primitivetype.h
  27. +0 −455 native/common/include/jp_primitivetypes.h
  28. +0 −5 native/common/include/jp_proxy.h
  29. +33 −23 native/common/include/{jp_referencequeue.h → jp_reference_queue.h}
  30. +71 −0 native/common/include/jp_shorttype.h
  31. +112 −0 native/common/include/jp_tracer.h
  32. +20 −17 native/common/include/jp_type.h
  33. +0 −168 native/common/include/jp_utility.h
  34. +64 −0 native/common/include/jp_voidtype.h
  35. +18 −42 native/common/include/jpype.h
  36. +17 −9 native/common/jp_array.cpp
  37. +16 −16 native/common/jp_arrayclass.cpp
  38. +199 −0 native/common/jp_booleantype.cpp
  39. +234 −0 native/common/jp_bytetype.cpp
  40. +220 −0 native/common/jp_chartype.cpp
  41. +54 −29 native/common/jp_class.cpp
  42. +3 −2 native/common/jp_classbase.cpp
  43. +74 −0 native/common/jp_cleaner.cpp
  44. +208 −0 native/common/jp_doubletype.cpp
  45. +1,296 −180 native/common/jp_env.cpp
  46. +14 −8 native/common/jp_field.cpp
  47. +220 −0 native/common/jp_floattype.cpp
  48. +71 −0 native/common/jp_hostref.cpp
  49. +215 −0 native/common/jp_inttype.cpp
  50. +0 −370 native/common/jp_javaenv.cpp
  51. +0 −1,760 native/common/jp_javaenv_autogen.cpp
  52. +69 −0 native/common/jp_jcharstring.cpp
  53. +222 −309 native/common/jp_jniutil.cpp
  54. +209 −0 native/common/jp_longtype.cpp
  55. +8 −1 native/common/jp_method.cpp
  56. +19 −17 native/common/jp_methodoverload.cpp
  57. +11 −4 native/common/jp_monitor.cpp
  58. +7 −5 native/common/jp_object.cpp
  59. +209 −0 native/common/jp_objecttype.cpp
  60. +0 −348 native/common/jp_objecttypes.cpp
  61. +0 −664 native/common/jp_primitivetypes.cpp
  62. +0 −1,369 native/common/jp_primitivetypes_autogen.cpp
  63. +41 −74 native/common/jp_proxy.cpp
  64. +152 −0 native/common/jp_reference_queue.cpp
  65. +209 −0 native/common/jp_shorttype.cpp
  66. +144 −0 native/common/jp_stringtype.cpp
  67. +75 −0 native/common/jp_tracer.cpp
  68. +8 −7 native/common/jp_typemanager.cpp
  69. +13 −13 native/common/jp_voidtype.cpp
  70. +54 −54 native/common/{jp_invocationhandler.cpp → thunk/jp_thunk_invocationhandler.h}
  71. +99 −99 native/common/{jp_referencequeue.cpp → thunk/jp_thunk_reference_queue.h}
  72. +50 −7 native/python/include/jpype_memory_view.h
  73. +1 −1 native/python/include/py_hostenv.h
  74. +5 −61 native/python/include/pythonenv.h
  75. +21 −6 native/python/jpype_javaarray.cpp
  76. +4 −11 native/python/jpype_javaclass.cpp
  77. +28 −29 native/python/jpype_javanio.cpp
  78. +10 −3 native/python/{jpype_memory_view.c → jpype_memory_view.cpp}
  79. +25 −118 native/python/jpype_module.cpp
  80. +8 −13 native/python/jpype_python.cpp
  81. +27 −198 native/python/py_class.cpp
  82. +20 −32 native/python/py_field.cpp
  83. +3 −2 native/python/py_hostenv.cpp
  84. +35 −21 native/python/py_method.cpp
  85. +17 −12 native/python/py_monitor.cpp
  86. +43 −0 native/python/pythonenv.cpp
  87. +10 −3 setup.py
  88. 0 test/test_jarray_fixes.py
  89. +1 −0 thunk/README
  90. +24 −0 thunk/build.xml
  91. +48 −0 thunk/dumpclass.py
  92. +16 −0 thunk/src/jpype/JPypeInvocationHandler.java
  93. +39 −0 thunk/src/jpype/ref/JPypeReference.java
  94. +93 −0 thunk/src/jpype/ref/JPypeReferenceQueue.java
@@ -7,6 +7,13 @@ This changelog *only* contains changes from the *first* pypi release (0.5.4.3) o
- Added extra verbiage to the to the raised exception when an overloaded
method could not be matched. It now prints a list of all possible method
signatures.
- Harded code to unattached threads and accessing java objects after shutdown.
- The following is now DEPRECATED
- jpype.reflect.* - All class information is available with .class_
- Python thread option for JPypeReferenceQueue. References are always handled with
with the Java cleanup routine. The undocumented setUsePythonThreadForDaemon()
will be removed at a future version.

- **0.6.3 - 2018-04-03**
- Java reference counting has been converted to use JNI
PushLocalFrame/PopLocalFrame. Several resource leaks
@@ -81,7 +81,6 @@ def attachToJVM(jvm):
_initialize()

def shutdownJVM():
_refdaemon.stop()
_jpype.shutdown()

def isThreadAttachedToJVM():
@@ -36,8 +36,6 @@ def __getattribute__(self, n):
import warnings
warnings.warn("JVM not started yet, can not inspect JPackage contents")
return n
if not _jpype.isThreadAttachedToJVM():
_jpype.attachThreadToJVM()
cc = _jpype.findClass(subname)
if cc is None:
# can only assume it is a sub-package then ...
@@ -28,5 +28,3 @@ def _run():

threading.Thread(target=_run).start()

def stop():
_jpype.stopReferenceQueue()
@@ -84,7 +84,7 @@ def _copyProperties(out, mc):
def _getStaticMethods(cls):
global _modifier
static = {}
for u in cls.__javaclass__.getMethods():
for u in cls.class_.getMethods():
if not _modifier.isStatic(u.getModifiers()):
continue
name = _keywordWrap(u.getName())
@@ -16,31 +16,33 @@
#*****************************************************************************
import _jpype

# FIXME this class is entirely replaced with calls to .class_ and should likely be deprecated.

def _initialize() :
pass

def getConstructors(clas):
return clas.__javaclass__.getConstructors()
return clas.class_.getConstructors()[:]

def getDeclaredConstructors(clas):
return clas.__javaclass__.getDeclaredConstructors()
return clas.class_.getDeclaredConstructors()[:]

def getDeclaredFields(clas) :
'''Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object.'''
return clas.__javaclass__.getDeclaredFields()
return clas.class_.getDeclaredFields()[:]

def getDeclaredMethods(clas):
'''Returns an array of Method objects reflecting all the methods declared by the class or interface represented by this Class object.'''
return clas.__javaclass__.getDeclaredMethods()
return clas.class_.getDeclaredMethods()[:]

def getFields(clas):
'''Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object.'''
return clas.__javaclass__.getFields()
return clas.class_.getFields()[:]

def getMethods(clas):
'''Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.'''
return clas.__javaclass__.getMethods()
return clas.class_.getMethods()[:]

def getModifiers(clas):
'''Returns the Java language modifiers for this class or interface, encoded in an integer.'''
return clas.__javaclass__.getModifiers()
return clas.class_.getModifiers()
@@ -0,0 +1,68 @@
/*****************************************************************************
Copyright 2004 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
#ifndef _JP_BOOLEAN_TYPE_H_
#define _JP_BOOLEAN_TYPE_H_

class JPBooleanType : public JPPrimitiveType
{
public :
JPBooleanType() : JPPrimitiveType(JPTypeName::_boolean, false, JPTypeName::fromSimple("java.lang.Boolean"))
{
}

virtual ~JPBooleanType()
{
}

public :
typedef jboolean type_t;
typedef jbooleanArray array_t;
inline jboolean& field(jvalue& v) { return v.z; }
inline jboolean field(const jvalue& v) const { return v.z; }

public : // JPType implementation
virtual HostRef* getStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, JPTypeName& tgtType);
virtual void setStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, HostRef* val);
virtual HostRef* getInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, JPTypeName& tgtType);
virtual void setInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, HostRef* val);
virtual HostRef* asHostObject(jvalue val);
virtual HostRef* asHostObjectFromObject(jvalue val);
virtual EMatchType canConvertToJava(HostRef* obj);
virtual jvalue convertToJava(HostRef* obj);

virtual HostRef* invokeStatic(JPJavaFrame& frame, jclass, jmethodID, jvalue*);
virtual HostRef* invoke(JPJavaFrame& frame, jobject, jclass, jmethodID, jvalue*);

virtual jarray newArrayInstance(JPJavaFrame& frame, int size);
virtual vector<HostRef*> getArrayRange(JPJavaFrame& frame, jarray, int start, int length);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int start, int length, vector<HostRef*>& vals);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int, int, PyObject*);
virtual HostRef* getArrayItem(JPJavaFrame& frame, jarray, int ndx);
virtual void setArrayItem(JPJavaFrame& frame, jarray, int ndx, HostRef* val);
virtual PyObject* getArrayRangeToSequence(JPJavaFrame& frame, jarray, int start, int length);

virtual HostRef* convertToDirectBuffer(HostRef* src);

virtual bool isSubTypeOf(const JPType& other) const
{
JPTypeName::ETypes otherType = other.getName().getType();
return otherType == JPTypeName::_boolean;
}
};

#endif // _JP_BOOLEAN_TYPE_H_

@@ -0,0 +1,74 @@
/*****************************************************************************
Copyright 2004 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
#ifndef _JPBYTE_TYPE_H_
#define _JPBYTE_TYPE_H_

class JPByteType : public JPPrimitiveType
{
public :
JPByteType() : JPPrimitiveType(JPTypeName::_byte, false, JPTypeName::fromSimple("java.lang.Byte"))
{
}

virtual ~JPByteType()
{
}

public :
typedef jbyte type_t;
typedef jbyteArray array_t;
inline jbyte& field(jvalue& v) { return v.b; }
inline jbyte field(const jvalue& v) const { return v.b; }

public : // JPType implementation
virtual HostRef* getStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, JPTypeName& tgtType);
virtual void setStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, HostRef* val);
virtual HostRef* getInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, JPTypeName& tgtType);
virtual void setInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, HostRef* val);
virtual HostRef* asHostObject(jvalue val);
virtual HostRef* asHostObjectFromObject(jvalue val);
virtual EMatchType canConvertToJava(HostRef* obj);
virtual jvalue convertToJava(HostRef* obj);

virtual HostRef* invokeStatic(JPJavaFrame& frame, jclass, jmethodID, jvalue*);
virtual HostRef* invoke(JPJavaFrame& frame, jobject, jclass, jmethodID, jvalue*);

virtual jarray newArrayInstance(JPJavaFrame& frame, int size);
virtual vector<HostRef*> getArrayRange(JPJavaFrame& frame, jarray, int start, int length);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int start, int length, vector<HostRef*>& vals);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int, int, PyObject*);
virtual HostRef* getArrayItem(JPJavaFrame& frame, jarray, int ndx);
virtual void setArrayItem(JPJavaFrame& frame, jarray, int ndx, HostRef* val);
// this returns tuple instead of list, for performance reasons
virtual PyObject* getArrayRangeToSequence(JPJavaFrame& frame, jarray, int start, int length);

virtual HostRef* convertToDirectBuffer(HostRef* src);

virtual bool isSubTypeOf(const JPType& other) const
{
JPTypeName::ETypes otherType = other.getName().getType();
return otherType == JPTypeName::_byte
|| otherType == JPTypeName::_short
|| otherType == JPTypeName::_int
|| otherType == JPTypeName::_long
|| otherType == JPTypeName::_float
|| otherType == JPTypeName::_double;
}
};

#endif // _JPBYTE_TYPE_H_

@@ -0,0 +1,72 @@
/*****************************************************************************
Copyright 2004 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
#ifndef _JP_CHAR_TYPE_H_
#define _JP_CHAR_TYPE_H_

class JPCharType : public JPPrimitiveType
{
public :
JPCharType() : JPPrimitiveType(JPTypeName::_char, false, JPTypeName::fromSimple("java.lang.Character"))
{
}

virtual ~JPCharType()
{
}

public :
typedef jchar type_t;
typedef jcharArray array_t;
inline jchar& field(jvalue& v) { return v.c; }
inline jchar field(const jvalue& v) const { return v.c; }

public : // JPType implementation
virtual HostRef* getStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, JPTypeName& tgtType);
virtual void setStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, HostRef* val);
virtual HostRef* getInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, JPTypeName& tgtType);
virtual void setInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, HostRef* val);
virtual HostRef* asHostObject(jvalue val);
virtual HostRef* asHostObjectFromObject(jvalue val);
virtual EMatchType canConvertToJava(HostRef* obj);
virtual jvalue convertToJava(HostRef* obj);

virtual HostRef* invokeStatic(JPJavaFrame& frame, jclass, jmethodID, jvalue*);
virtual HostRef* invoke(JPJavaFrame& frame, jobject, jclass, jmethodID, jvalue*);

virtual jarray newArrayInstance(JPJavaFrame& frame, int size);
virtual vector<HostRef*> getArrayRange(JPJavaFrame& frame, jarray, int start, int length);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int start, int length, vector<HostRef*>& vals);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int, int, PyObject*);
virtual HostRef* getArrayItem(JPJavaFrame& frame, jarray, int ndx);
virtual void setArrayItem(JPJavaFrame& frame, jarray, int ndx, HostRef* val);
virtual PyObject* getArrayRangeToSequence(JPJavaFrame& frame, jarray, int start, int length);

virtual HostRef* convertToDirectBuffer(HostRef* src);

virtual bool isSubTypeOf(const JPType& other) const
{
JPTypeName::ETypes otherType = other.getName().getType();
return otherType == JPTypeName::_char
|| otherType == JPTypeName::_int
|| otherType == JPTypeName::_long
|| otherType == JPTypeName::_float
|| otherType == JPTypeName::_double;
}
};

#endif // _JP-CHAR_TYPE_H_

@@ -39,12 +39,12 @@ public : // JPType implementation

virtual jclass getClass() const
{
return (jclass)JPEnv::getJava()->NewLocalRef(m_Class);
return m_Class;
}

protected :
JPTypeName m_Name;
jclass m_Class;
JPTypeName m_Name;
jclass m_Class;
};

#endif // _JPCLASS_BASE_H_
@@ -0,0 +1,67 @@
/*****************************************************************************
Copyright 2004 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
#ifndef _JP_DOUBLE_TYPE_H_
#define _JP_DOUBLE_TYPE_H_

class JPDoubleType : public JPPrimitiveType
{
public :
JPDoubleType() : JPPrimitiveType(JPTypeName::_double, false, JPTypeName::fromSimple("java.lang.Double"))
{
}

virtual ~JPDoubleType()
{
}

public :
typedef jdouble type_t;
typedef jdoubleArray array_t;
inline jdouble& field(jvalue& v) { return v.d; }
inline jdouble field(const jvalue& v) const { return v.d; }

public : // JPType implementation
virtual HostRef* getStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, JPTypeName& tgtType);
virtual void setStaticValue(JPJavaFrame& frame, jclass c, jfieldID fid, HostRef* val);
virtual HostRef* getInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, JPTypeName& tgtType);
virtual void setInstanceValue(JPJavaFrame& frame, jobject c, jfieldID fid, HostRef* val);
virtual HostRef* asHostObject(jvalue val);
virtual HostRef* asHostObjectFromObject(jvalue val);
virtual EMatchType canConvertToJava(HostRef* obj);
virtual jvalue convertToJava(HostRef* obj);

virtual HostRef* invokeStatic(JPJavaFrame& frame, jclass, jmethodID, jvalue*);
virtual HostRef* invoke(JPJavaFrame& frame, jobject, jclass, jmethodID, jvalue*);

virtual jarray newArrayInstance(JPJavaFrame& frame, int size);
virtual vector<HostRef*> getArrayRange(JPJavaFrame& frame, jarray, int start, int length);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int start, int length, vector<HostRef*>& vals);
virtual void setArrayRange(JPJavaFrame& frame, jarray, int, int, PyObject*);
virtual HostRef* getArrayItem(JPJavaFrame& frame, jarray, int ndx);
virtual void setArrayItem(JPJavaFrame& frame, jarray, int ndx, HostRef* val);
virtual PyObject* getArrayRangeToSequence(JPJavaFrame& frame, jarray, int start, int length);

virtual HostRef* convertToDirectBuffer(HostRef* src);

virtual bool isSubTypeOf(const JPType& other) const
{
JPTypeName::ETypes otherType = other.getName().getType();
return otherType == JPTypeName::_double;
}
};

#endif // _JP_DOUBLE_TYPE_H_
Oops, something went wrong.

0 comments on commit df4ba23

Please sign in to comment.
You can’t perform that action at this time.