Closed MrFizzyBubbs closed 1 year ago
There are no hooks in JPype that one could catch every Java call. However, you can monkey patch to create such a hook using the fact that all JPype calls go through the same private internal classes. If you are trying to intercept methods it would have to go through _JMethod
while setting or getting any field goes through _JField
.
Here is a short example:
import jpype
import jpype.imports
jpype.startJVM()
# Use a monkey patch of _jpype._JMethod where all Java methods calls go through
import _jpype # we need to access the private classes
jmethod = _jpype._JMethod # method calls all go through _JMethod
call = getattr(jmethod, "__call__") # first we have to move the old call method out of the way
setattr(jmethod, "_c", call)
# define a user hook
def hook(self, *args):
print("Pre")
ret = self._c(*args) # call the real Java implementation
print("Post")
return ret
setattr(jmethod, "__call__", hook) # replace the call method with user hook
# Test it
import java
mystr = java.lang.String("hello")
print(mystr.substring(3))
That is my best guess. Please note this will void the warrantee.
Thank you for the prompt and detailed answer, the bit about all method calls routing through _jpype._JMethod
is exactly what I was looking for. I appreciate all the work that you and others have done on JPype!
For those who are interested in doing something similar, I found that I also needed to patch _JClass.__call__
in addition to _JMethod.__call__
.
I would like to execute a function after every Java function call to monitor the state of my
.jar
file. I am able to achieve this with a tracer (see below) but this is not optimal for many reasons. Is there a better approach in jpype?