我的代码遇到了障碍,希望有人能提供帮助。
我有一个正在构建的应用程序,我被迫使用 Java 并将其部署到 Glassfish 3.1 服务器。这不是我通常喜欢的工作方式,因为我更像是一名 Python 开发人员。因此,我已经使用 Jython 2.7,并且正在使用 Flask。
但是,我正在使用 Blueprints 图形 DB API 的 Bitsy 实现来构建一个图形,该图形表示我的应用程序将在基于 REST 的 API(源自 Oracle DB,使用 JPA 2.0)中提供的数据。
我已经成功地使用以下代码构建了我的图表:
from __future__ import division, absolute_import, print_function
import collections
import java.lang.Class
import java.lang.Runtime
import java.nio.file.Paths
import os
import tempfile
import concurrent.futures
from flask import Flask
import contextlib2 as contextlib
import javax.persistence.Persistence as JPA
import com.lambdazen.bitsy.BitsyGraph
import java.lang.management.ManagementFactory
app = Flask(__name__.split('.')[0])
def process_indi(pool, graph, parent_key, indi_key):
"""
Processes a single indicator to be loaded on the graph.
"""
indi_class = java.lang.Class.forName("pampas.db.r.models.Indi")
manager_factory = JPA.createEntityManagerFactory("pampas-r")
manager = manager_factory.createEntityManager()
try:
indi = manager.createNamedQuery('Indi.findByIndiKey', indi_class)
indi = indi.setParameter("indi_key", indi_key)
indi = indi.singleResult
trans = graph.newTransaction()
try:
vert = trans.addVertex(None)
vert.setProperty('indi_key', indi.cidIndicatorKey)
if indi_key == 'SYSTEM_ROOT':
region_class = java.lang.Class.forName("pampas.db.r.models.Region")
region = manager.createNamedQuery('Region.findThis', region_class)
region = region.singleResult
vert.setProperty('name', region.cidRegion)
status_text_class = java.lang.Class.forName("pampas.db.r.models.StatusText")
status_text = manager.createNamedQuery('StatusText.findAll', status_text_class)
states = {
state.cidStatus: state.ctxDesc
for state in status_text.resultList
}
vert.setProperty('states', states)
else:
vert.setProperty('name', indi.ctxDesc)
states = {
threshold.id.nnoStatus: threshold.ctxDesc
for threshold in indi.thresholds
}
if states:
vert.setProperty('states', states)
if indi.ctxTooltip is not None:
vert.setProperty('tooltip', indi.ctxTooltip)
if indi.ctxHyperlink is not None:
vert.setProperty('link', indi.ctxHyperlink)
with contextlib.suppress(AttributeError):
vert.setProperty('status', indi.script.statusText.cidStatus)
vert.setProperty('last_updated', indi.script.dtCurrent)
with contextlib.suppress(AttributeError):
if indi.vSuppressActives.size() > 0:
for suppress in indi.vSuppressActives:
print(suppress.ctxComment)
vert.setProperty('suppressed', True)
with contextlib.suppress(AttributeError):
key_value = False
edit_list = False
for plugin_value in indi.pluginValues:
if plugin_value.pluginGroup.ctxEditType == 'KEY_VALUE':
key_value = True
elif plugin_value.pluginGroup.ctxEditType == 'LIST':
edit_list = True
if key_value and edit_list:
break
if key_value:
vert.setProperty('key_value', key_value)
if edit_list:
vert.setProperty('edit_list', edit_list)
if parent_key is not None:
parent = None
for item in trans.getVertices('indi_key', indi.parent.cidIndicatorKey):
parent = item
break
trans.addEdge(None, vert, parent, 'ancestor')
print('{parent} => {child}'.format(
parent=parent.getProperty('name'), child=vert.getProperty('name')))
else:
print(vert.getProperty('name'))
finally:
trans.commit()
futures = tuple(
pool.submit(process_indi, pool, graph, vert, child.cidIndicatorKey)
for child in indi.children
)
finally:
manager.close()
return futures
@app.route('/gen_tree')
def gen_tree():
"""
Generate the tree and load it into the Bitsy (Blueprints) GraphDB.
"""
db_path = os.path.join(tempfile.gettempdir(), 'pampas', 'graph')
with contextlib.suppress(OSError):
os.makedirs(db_path)
db_path = java.nio.file.Paths.get(db_path)
graph = com.lambdazen.bitsy.BitsyGraph(db_path)
vertex_class = java.lang.Class.forName("com.tinkerpop.blueprints.Vertex")
try:
trans = graph.newTransaction()
try:
trans.createKeyIndex('indi_key', vertex_class)
trans.createKeyIndex('suppressed', vertex_class)
finally:
trans.commit()
futures = collections.deque()
runtime = java.lang.Runtime.getRuntime()
cpu_count = runtime.availableProcessors()
with concurrent.futures.ThreadPoolExecutor(cpu_count * 5) as pool:
batch = process_indi(pool, graph, None, 'SYSTEM_ROOT')
if batch:
futures.append(batch)
while futures:
block = futures.popleft()
for future in concurrent.futures.as_completed(block):
batch = future.result()
if batch:
futures.append(batch)
print('Num Vertices:', len(tuple(graph.getVertices())), '| Num Edges:', len(tuple(graph.getEdges())))
finally:
graph.shutdown()
return 'Graph DB built.'
这很好用,并完全按照我的意愿生成我的图表。
但是,当我添加以下内容时:
import com.tinkerpop.blueprints.util.wrappers.readonly.ReadOnlyGraph
@app.route('/')
def read_tree():
db_path = os.path.join(tempfile.gettempdir(), 'pampas', 'graph')
with contextlib.suppress(OSError):
os.makedirs(db_path)
db_path = java.nio.file.Paths.get(db_path)
graph = com.lambdazen.bitsy.BitsyGraph(db_path)
rograph = com.tinkerpop.blueprints.util.wrappers.readonly.ReadOnlyGraph(graph)
root = None
for node in rograph.getVertices('indi_key', 'SYSTEM_ROOT'):
root = node
break
return root.getProperty('name')
我尝试运行这段代码(从http://localhost:8080/data/基于其他配置),我得到以下信息:
2016-08-31T11:02:06.745-0400|Info: PWC1412: WebModule[null] ServletContext.log():debug: Attempting to import application callable 'wsgi.application'
2016-08-31T11:02:06.746-0400|Info: PWC1412: WebModule[null] ServletContext.log():debug: Application is <Flask 'pampas'>
2016-08-31T11:02:06.862-0400|Warning: StandardWrapperValve[modjy]: PWC1406: Servlet.service() for servlet modjy threw exception
com.lambdazen.bitsy.BitsyException: INSTANCE_ALREADY_EXISTS: A BitsyGraph object with the same path has been registered with the MBeanServer. Creating multiple instances of BitsyGraph (without calling shutdown) will cause data corruption. Path C:\Users\QTB0065\AppData\Local\Temp\pampas\graph
at com.lambdazen.bitsy.BitsyGraph.<init>(BitsyGraph.java:91)
at com.lambdazen.bitsy.BitsyGraph.<init>(BitsyGraph.java:63)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.python.core.PyReflectedConstructor.constructProxy(PyReflectedConstructor.java:211)
at org.python.core.PyReflectedConstructor.__call__(PyReflectedConstructor.java:180)
at org.python.core.PyObject.__call__(PyObject.java:419)
at org.python.core.PyMethod.instancemethod___call__(PyMethod.java:237)
at org.python.core.PyMethod.__call__(PyMethod.java:228)
at org.python.core.PyMethod.__call__(PyMethod.java:223)
at org.python.core.Deriveds.dispatch__init__(Deriveds.java:19)
at org.python.core.PyObjectDerived.dispatch__init__(PyObjectDerived.java:1112)
at org.python.core.PyType.type___call__(PyType.java:1713)
at org.python.core.PyType.__call__(PyType.java:1696)
at org.python.core.PyObject.__call__(PyObject.java:461)
at org.python.core.PyObject.__call__(PyObject.java:465)
at pampas.test$py.read_tree$1(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\pampas\test.py:74)
at pampas.test$py.call_function(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\pampas\test.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:307)
at org.python.core.PyFunction.function___call__(PyFunction.java:471)
at org.python.core.PyFunction.__call__(PyFunction.java:466)
at org.python.core.PyFunction.__call__(PyFunction.java:461)
at org.python.core.PyObject._callextra(PyObject.java:601)
at flask.app$py.dispatch_request$69(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py:1625)
at flask.app$py.call_function(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:138)
at org.python.core.PyFunction.__call__(PyFunction.java:413)
at org.python.core.PyMethod.__call__(PyMethod.java:126)
at flask.app$py.full_dispatch_request$70(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py:1645)
at flask.app$py.call_function(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:138)
at org.python.core.PyFunction.__call__(PyFunction.java:413)
at org.python.core.PyMethod.__call__(PyMethod.java:126)
at flask.app$py.wsgi_app$85(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py:1996)
at flask.app$py.call_function(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:170)
at org.python.core.PyFunction.__call__(PyFunction.java:434)
at org.python.core.PyMethod.__call__(PyMethod.java:156)
at flask.app$py.__call__$86(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py:2000)
at flask.app$py.call_function(C:\Users\QTB0065\AppData\Local\Temp\pip-build-bmhjzf\flask\flask\app.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:170)
at org.python.core.PyFunction.__call__(PyFunction.java:434)
at org.python.core.PyMethod.__call__(PyMethod.java:156)
at modjy.modjy$py.call_application$10(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\WEB-INF\lib\jython.jar\Lib\modjy\modjy.py:109)
at modjy.modjy$py.call_function(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\WEB-INF\lib\jython.jar\Lib\modjy\modjy.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:188)
at org.python.core.PyFunction.__call__(PyFunction.java:446)
at org.python.core.PyMethod.__call__(PyMethod.java:171)
at modjy.modjy$py.dispatch_to_application$9(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\WEB-INF\lib\jython.jar\Lib\modjy\modjy.py:103)
at modjy.modjy$py.call_function(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\WEB-INF\lib\jython.jar\Lib\modjy\modjy.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:188)
at org.python.core.PyFunction.__call__(PyFunction.java:446)
at org.python.core.PyMethod.__call__(PyMethod.java:171)
at modjy.modjy$py.service$7(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\WEB-INF\lib\jython.jar\Lib\modjy\modjy.py:80)
at modjy.modjy$py.call_function(C:\Users\QTB0065\Apps\glassfish3\glassfish\domains\pampas\applications\pampas-be\WEB-INF\lib\jython.jar\Lib\modjy\modjy.py)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyBaseCode.call(PyBaseCode.java:307)
at org.python.core.PyBaseCode.call(PyBaseCode.java:198)
at org.python.core.PyFunction.__call__(PyFunction.java:482)
at org.python.core.PyMethod.instancemethod___call__(PyMethod.java:237)
at org.python.core.PyMethod.__call__(PyMethod.java:228)
at org.python.core.PyMethod.__call__(PyMethod.java:218)
at org.python.core.PyMethod.__call__(PyMethod.java:213)
at org.python.core.PyObject._jcallexc(PyObject.java:3626)
at org.python.proxies.modjy.modjy$modjy_servlet$0.service(Unknown Source)
at com.xhaus.modjy.ModjyJServlet.service(ModjyJServlet.java:142)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
特别感兴趣的是:
com.lambdazen.bitsy.BitsyException:INSTANCE_ALREADY_EXISTS:具有相同路径的 BitsyGraph 对象已向 MBeanServer 注册。创建多个 BitsyGraph 实例(不调用 shutdown)将导致数据损坏。路径 C:\Users\QTB0065\AppData\Local\Temp\pampas\graph
这显然是因为我会生成我的图表,然后尝试从同一服务器上的另一个 url ("servlet" [sic]) 读取它。如果我已经注册了一个 BitsyGraph 对象,并且它存在,有什么方法可以将该实例从一个“servlet”传递到另一个?