jython2.2.1 属性错误:“javainstance”对象没有属性“__call__”;

发布于 2024-12-04 23:21:43 字数 2329 浏览 0 评论 0原文

我在尝试运行嵌入在已编译的 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

这是运行上述代码时的输出:

  1. TestRunners __call__() 方法将调用 A 类实例的 work() 方法,并且打印 Web 服务存根的 toString 输出。
  2. 打印“正在调用方法调用”消息。
  3. “In methodcall”消息永远不会被打印,而是我得到:AttributeError: 'javainstance' object has no attribute '__call__'。堆栈跟踪以 self.b.methodcall() 结尾

您知道为什么调用 self.b.methodcall() 会导致 AttributeError: ' javainstance' 对象没有属性 __call__

为问题添加一些上下文...

  1. 我正在尝试使用 Groovy 类来执行 Grinder 工作线程在我们对产品进行性能测试时将执行的工作。
    • 我使用 groovy 只是为了“减少冗长的代码”,但如果是 groovy 导致了问题,则可能必须切换到普通的旧 java。
  2. 这样做的原因是我需要找出 Grinder 对于给定的测试场景实际使用了哪些文件。
    • 我们有数百个 *.py 文件和配置文件等,但只有其中的一个子集用于一个特定测试场景。所有这些都用于某些测试场景。
    • 这使得“初学者”很难理解如何配置测试,因此我尝试构建一个“测试配置器向导”来设置测试场景,而不强制用户/测试人员编辑所有配置文件手动。
    • 此向导将从“存储库”收集相关文件,并将它们放入一个文件夹中,“Grinder Console”可以将它们呈现给用户。

因此,我用来找出 Grinder 使用哪些文件的方法是使用 AOP (AspectJ) 捕获来自以下任何代码对 java.io.FileInputStream(java.io.File) 的所有调用org.python.utilorg.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:

  1. The TestRunners __call__() method will invoke the work() method of a class A instance, and the webservice stub's toString output is printed.
  2. The "Calling methodcall" message is printed.
  3. The "In methodcall" message is never printed, and instead I get: AttributeError: 'javainstance' object has no attribute '__call__'. The stacktrace ends with self.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...

  1. 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.
  2. 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.

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 AttributeErrorproblem 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文