【发布时间】:2015-11-25 19:23:38
【问题描述】:
我正在开发包含用多种语言编写的组件的应用程序。我正在尝试获得在 Jython 中工作的 Java 中运行良好的功能。 Java 通过 JNI 访问并由 SWIG 包装了一些本机/C++ 功能。
每当我尝试导入项目中的所有类时,都会收到无法链接 PROJECTJNI 的错误。这是我要制作的最小案例:
import sys
sys.path.append('PROJECT.jar')
from com.whatever.project import *
这是执行时的错误消息:
$ jython Bootstrap.py
"my" variable $jythonHome masks earlier declaration in same scope at /usr/bin/jython line 15.
Traceback (most recent call last):
File "Bootstrap.py", line 9, in <module>
from com.whatever.project import *
java.lang.UnsatisfiedLinkError: com.whatever.project.PROJECTJNI.swig_module_init()V
at com.whatever.project.PROJECTJNI.swig_module_init(Native Method)
at com.whatever.project.PROJECTJNI.<clinit>(PROJECTJNI.java:974)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:278)
at org.python.core.Py.loadAndInitClass(Py.java:909)
at org.python.core.Py.findClassInternal(Py.java:844)
at org.python.core.Py.findClass(Py.java:869)
at org.python.core.packagecache.PackageManager.basicDoDir(PackageManager.java:107)
at org.python.core.packagecache.SysPackageManager.doDir(SysPackageManager.java:138)
at org.python.core.PyJavaPackage.fillDir(PyJavaPackage.java:123)
at org.python.core.imp.importAll(imp.java:1051)
at org.python.core.imp.importAll(imp.java:1039)
at org.python.pycode._pyx0.f$0(Bootstrap.py:9)
at org.python.pycode._pyx0.call_function(Bootstrap.py)
at org.python.core.PyTableCode.call(PyTableCode.java:165)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1275)
at org.python.util.PythonInterpreter.execfile(PythonInterpreter.java:235)
at org.python.util.jython.run(jython.java:247)
at org.python.util.jython.main(jython.java:129)
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: com.whatever.project.PROJECTJNI.swig_module_init()V
第 15 行的内容在我们调用 jython 时出现,我们一直忽略它。
我们可以通过简单地一次加载一个类来让 Java 项目中的类工作:
com.whatever.project import Class1
com.whatever.project import Class2
...
com.whatever.project import Class50
这是非常不切实际的,因为即使是简短的 Python 脚本,我们也可能需要十几个类。其中许多是我们正在捕获的具有独特类型的例外。因此,任何能够稳健地处理错误的东西都可能需要大量的类。
根据jython documentation,我应该能够隐藏 PROJECTJNI,因此不会通过执行此类操作来加载它,但我发现文档不太清楚。这是我尝试过的:
import com.whatever.project
__all__ = dir(com.whatever.project)
__all__.remove('PROJECTJNI')
from com.whatever.project import *
但这会因错误而失败,并且仍在尝试加载 PROJECTJNI。
我还尝试修复本机可执行文件,以便它可以与正确链接。我了解到另一个使用 JRuby 的小组没有任何问题,包括所有内容,所以我决定检查源代码和二进制文件。我在 Swig 创建的文件 Project_wrap.cpp 中找到了 void swig_module_init()。它隐藏在宏后面,但它就在那里,并且 objdump 确认:
$objdump libPROJECT.so -t |grep PROJECTJNI |grep init
000000000051a900 l O .data 00000000000009d0 _ZZ59Java_com_whatever_project_PROJECTJNI_swig_1module_1initE7methods
0000000000263f66 g F .text 00000000000000d1 Java_com_whatever_project_PROJECTJNI_swig_1module_1init
我的问题排查步骤是否有问题?是 Jython 中的错误吗?是否有一个简单的 Python 解决方法可以让它跳过加载 PROJECTJNI?
任何让我跳过链接或正确链接的内容都将被接受。
【问题讨论】:
标签: java c++ import jython swig