jython2.2.1 属性错误:“javainstance”对象没有属性“__call__”;
我在尝试运行嵌入在已编译的 groovy 应用程序中的 jython 代码时遇到问题。相同的 jython 代码在嵌入 java 应用程序(The Grinder 3.1)时工作正常。
在 groovy 代码中,我使用 org.python.util.PythonInterpreter 类(来自 jython 2.2.1)来创建名为 的类的可调用实例TestRunner(这是 The Grinder 的要求)。
说明性 jython 代码示例:
class TestRunner:
def __init__(self):
doinitstuff()
def __call__():
a = A()
a.work()
class A:
def __init__(self):
self.b = B()
def work(self):
print "Calling methodcall"
self.b.methodcall()
class B:
def __init__(self):
self.webservice = WebServiceStubImplementedInJava()
print str(self.webservice)
def methodcall(self):
print "In methodcall"
try:
return self.webservice.soapmethod()
except:
log_error()
raise
这是运行上述代码时的输出:
- TestRunners
__call__()
方法将调用 A 类实例的work()
方法,并且打印 Web 服务存根的 toString 输出。 - 打印“正在调用方法调用”消息。
- “In methodcall”消息永远不会被打印,而是我得到:
AttributeError: 'javainstance' object has no attribute '__call__'
。堆栈跟踪以self.b.methodcall()
结尾
您知道为什么调用 self.b.methodcall()
会导致 AttributeError: ' javainstance' 对象没有属性 __call__
为问题添加一些上下文...
- 我正在尝试使用 Groovy 类来执行 Grinder 工作线程在我们对产品进行性能测试时将执行的工作。
- 我使用 groovy 只是为了“减少冗长的代码”,但如果是 groovy 导致了问题,则可能必须切换到普通的旧 java。
- 这样做的原因是我需要找出 Grinder 对于给定的测试场景实际使用了哪些文件。
- 我们有数百个
*.py
文件和配置文件等,但只有其中的一个子集用于一个特定测试场景。所有这些都用于某些测试场景。 - 这使得“初学者”很难理解如何配置测试,因此我尝试构建一个“测试配置器向导”来设置测试场景,而不强制用户/测试人员编辑所有配置文件手动。
- 此向导将从“存储库”收集相关文件,并将它们放入一个文件夹中,“Grinder Console”可以将它们呈现给用户。
- 我们有数百个
因此,我用来找出 Grinder 使用哪些文件的方法是使用 AOP (AspectJ) 捕获来自以下任何代码对 java.io.FileInputStream(java.io.File)
的所有调用org.python.util
和 org.python.core
软件包。 我对这些连接点应用的“建议”是将文件名打印到 System.out。 我为此使用加载时编织,因此我可以运行 groovy/java/jython 代码,而无需 已启用 AOP。无论我是否启用了 AOP,都会出现 AttributeError 问题。
我模糊地怀疑 AttributeError
问题可能是由“groovy”类执行 PythonInterpreter 方法时某些类加载器不匹配引起的,但我对此还很不确定。 我不确定 groovy 在加载类时是否进行任何类型的运行时字节码编辑,以及这是否会混淆 PythonInterpreter。
groovy 代码本身是预编译的,因此我使用常规 java.exe 来启动该进程。
I'm having trouble trying to run jython code embedded in a compiled groovy application. The same jython code works fine when it is embedded in a java application (The Grinder 3.1)
In the groovy code I use the org.python.util.PythonInterpreter class (from jython 2.2.1) to create a callable instance of a class called TestRunner (this is a requirement from The Grinder).
Illustrative jython code example:
class TestRunner:
def __init__(self):
doinitstuff()
def __call__():
a = A()
a.work()
class A:
def __init__(self):
self.b = B()
def work(self):
print "Calling methodcall"
self.b.methodcall()
class B:
def __init__(self):
self.webservice = WebServiceStubImplementedInJava()
print str(self.webservice)
def methodcall(self):
print "In methodcall"
try:
return self.webservice.soapmethod()
except:
log_error()
raise
Here is the output when I run the above code:
- The TestRunners
__call__()
method will invoke thework()
method of a class A instance, and the webservice stub's toString output is printed. - The "Calling methodcall" message is printed.
- The "In methodcall" message is never printed, and instead I get:
AttributeError: 'javainstance' object has no attribute '__call__'
. The stacktrace ends withself.b.methodcall()
Do you have any idea why the invocation of self.b.methodcall()
should result in AttributeError: 'javainstance' object has no attribute __call__
Adding some context to the problem...
- I'm trying to use a Groovy class to execute the work that a Grinder worker thread would perform when we performance test our product.
- I use groovy just for the sake of "less verbose code", but might have to switch over to plain old java if it's groovy that causes the problem.
- The reason for doing this is that I need to find out which files are actually used by Grinder for a given test scenario.
- We have hundreds of
*.py
files and configuration files etc, but only a subset of them are used for one specific test scenario. All of them are used in some test scenario. - This makes it quite hard for a "beginner" to understand how to configure a test so I'm trying to build a "test configurator wizard" that set up a test scenario without forcing the user/tester to edit all config files manually.
- This wizard will collect the relevant files from a "repository" and put them in a folder where the "Grinder Console" can present them to the user.
- We have hundreds of
So, the way I use to find out which files are used by Grinder is to use AOP (AspectJ) to capture all calls to java.io.FileInputStream(java.io.File)
from any code in the org.python.util
and org.python.core
packages.
The "advice" I apply to these join-points is to print the file name to System.out
.
I use load-time weaving for this, so I can run the groovy/java/jython code with our without
AOP enabled. The AttributeError
problem occurs regardless if I have AOP enabled or not.
I have a vague suspicion that the AttributeError
problem could be caused by some classloader mismatch when a "groovy" class executes the PythonInterpreter methods, but I'm far from sure about this.
I'm not sure if groovy is doing any kind of runtime bytecode editing when it loads classes and if that confuses the PythonInterpreter.
The groovy code itself is precompiled so I use the regular java.exe to launch the process.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论