Python 为什么从粘贴应用程序中创建neo4j.GraphDatabase会导致segfault?

Python 为什么从粘贴应用程序中创建neo4j.GraphDatabase会导致segfault?,python,paste,neo4j,webob,Python,Paste,Neo4j,Webob,下面的代码导致Java发生故障: import os.path import neo4j from paste import httpserver, fileapp import tempfile from webob.dec import wsgify from webob import Response, Request HOST = '127.0.0.1' PORT = 8080 class DebugApp(object): @wsgify def __call__(

下面的代码导致Java发生故障:

import os.path
import neo4j
from paste import httpserver, fileapp
import tempfile
from webob.dec import wsgify
from webob import Response, Request

HOST = '127.0.0.1'
PORT = 8080

class DebugApp(object):
    @wsgify
    def __call__(self, req):

        # db = neo4j.GraphDatabase(tempfile.mkdtemp())
        db = neo4j.GraphDatabase(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data'))
        return Response(body='it worked')

def main():
    app = DebugApp()
    httpserver.serve(app, host=HOST, port=PORT)

if __name__ == '__main__':
    main()
>>> import webob
>>> import app
>>> debug_app = app.DebugApp()
>>> response = debug_app(webob.Request.blank('/'))
>>> response.body
'it worked'
要复制,首先将代码保存到一个文件(比如app.py),然后运行
python app.py
。然后在浏览器中尝试;您应该看到Java崩溃处理程序

Java堆栈跟踪的顶部如下所示:

Stack: [0xb42e7000,0xb4ae8000],  sp=0xb4ae44f0,  free space=8181k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [_jpype.so+0x26497]  JPJavaEnv::NewObjectA(_jclass*, _jmethodID*, jvalue*)+0x37
C  [_jpype.so+0x3c0e8]  JPMethodOverload::invokeConstructor(_jclass*, std::vector<HostRef*, std::allocator<HostRef*> >&)+0x178
C  [_jpype.so+0x3a417]  JPMethod::invokeConstructor(std::vector<HostRef*, std::allocator<HostRef*> >&)+0x47
C  [_jpype.so+0x1beba]  JPClass::newInstance(std::vector<HostRef*, std::allocator<HostRef*> >&)+0x2a
C  [_jpype.so+0x67b9c]  PyJPClass::newClassInstance(_object*, _object*)+0xfc
C  [python+0x96822]  PyEval_EvalFrameEx+0x4332
C  [python+0x991e7]  PyEval_EvalCodeEx+0x127
大概是因为我在那个例子中完全避免了粘贴。也许这与Paste使用线程阻碍neo4j有关?我在neo4j论坛上注意到了一个类似的问题:


…但这只发生在关机时。

问题不在于粘贴本身,而在于使用JPype的neo4j Python绑定。粘贴创建线程来处理传入的请求;neo4j应该是线程安全的,但是JPype在文档()中附带了以下警告:

“在大多数情况下,基于操作系统级线程(即posix线程)的python线程都可以正常工作。唯一要记住的是在线程体中调用jpype.attachThreadToJVM(),使JVM可以从该线程使用。对于不自己启动的线程,可以调用isThreadAttachedToJVM()进行检查。”

我找不到执行此操作的代码,但我认为neo4j绑定中的一些Java代码可能在导入时调用
attachThreadToJVM
。如果是这样,当一个请求通过粘贴传递给一个工作线程,然后该线程从neo4j获取数据时,它跨越了线程边界,JVM附件规则可能无法满足

通过仅在单个线程中运行
import neo4j
,可以避免崩溃。在上面的例子中,这是
threading.Thread
所针对的可调用对象

不幸的是,这意味着即使neo4j是线程安全的,但当从Python使用时,它也必须被限制为单个线程。但考虑到这一点,这并不令人失望


更新:维护人员响应(),调查问题,并检查修复。我不知道在哪个版本的neo4j中可以使用它,而且我再也找不到提交到他们的github repo(),因此这代表重新测试。

您是否使用新的Python绑定,信息如下:?是的,这些是我正在使用的绑定。欢迎使用StackOverflow。您可以/应该将此答案标记为已接受,以便其他人知道有解决方案。