Python 3.x 如何在Python中使用参数调用调用JMX操作?

Python 3.x 如何在Python中使用参数调用调用JMX操作?,python-3.x,jmx,jpype,Python 3.x,Jmx,Jpype,我试图使用Jpype从Python调用JMX操作,但在传递参数时出错 import jpype from jpype import java from jpype import javax HOST='localhost' PORT=9000 USER='' PASS='' URL = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi" % (HOST, PORT) #this it the path of your libjvm /usr/lib/jv

我试图使用Jpype从Python调用JMX操作,但在传递参数时出错

import jpype
from jpype import java
from jpype import javax

HOST='localhost'
PORT=9000
USER=''
PASS=''

URL = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi" % (HOST, PORT)
#this it the path of your libjvm /usr/lib/jvm/sun-jdk-<version>/jre/lib/amd64/server/libjvm.so on linux
jpype.startJVM("/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so")
java.lang.System.out.println("JVM load OK")

jhash = java.util.HashMap()
jarray=jpype.JArray(java.lang.String)([USER,PASS])
jhash.put (javax.management.remote.JMXConnector.CREDENTIALS, jarray);
jmxurl = javax.management.remote.JMXServiceURL(URL)
jmxsoc = javax.management.remote.JMXConnectorFactory.connect(jmxurl,jhash)
connection = jmxsoc.getMBeanServerConnection();

# This invoke operation works fine as it does not expect any arguments
object = 'Catalina:type=ThreadPool,name="http-nio-8080"'
attribute = "hasNegotiableProtocols"
print(connection.invoke(javax.management.ObjectName(object),attribute, None, None))

# This invoke operation expects string argument ("admin" in this case)
object = "Users:type=UserDatabase,database=UserDatabase"
opt = "findUser"
connection.invoke(javax.management.ObjectName(object),opt,'admin',None)
对于不涉及任何参数的操作,它工作得非常好

import jpype
from jpype import java
from jpype import javax

HOST='localhost'
PORT=9000
USER=''
PASS=''

URL = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi" % (HOST, PORT)
#this it the path of your libjvm /usr/lib/jvm/sun-jdk-<version>/jre/lib/amd64/server/libjvm.so on linux
jpype.startJVM("/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so")
java.lang.System.out.println("JVM load OK")

jhash = java.util.HashMap()
jarray=jpype.JArray(java.lang.String)([USER,PASS])
jhash.put (javax.management.remote.JMXConnector.CREDENTIALS, jarray);
jmxurl = javax.management.remote.JMXServiceURL(URL)
jmxsoc = javax.management.remote.JMXConnectorFactory.connect(jmxurl,jhash)
connection = jmxsoc.getMBeanServerConnection();

# This invoke operation works fine as it does not expect any arguments
object = 'Catalina:type=ThreadPool,name="http-nio-8080"'
attribute = "hasNegotiableProtocols"
print(connection.invoke(javax.management.ObjectName(object),attribute, None, None))

# This invoke operation expects string argument ("admin" in this case)
object = "Users:type=UserDatabase,database=UserDatabase"
opt = "findUser"
connection.invoke(javax.management.ObjectName(object),opt,'admin',None)
导入jpype
从jpype导入java
从jpype导入javax
HOST='localhost'
端口=9000
用户=“”
通过=“”
URL=“服务:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi“%(主机、端口)
#这是linux上libjvm/usr/lib/jvm/sunjdk-/jre/lib/amd64/server/libjvm.so的路径
jpype.startJVM(“/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so”)
java.lang.System.out.println(“JVM加载正常”)
jhash=java.util.HashMap()
jarray=jpype.jarray(java.lang.String)([USER,PASS])
jhash.put(javax.management.remote.JMXConnector.CREDENTIALS,jarray);
jmxurl=javax.management.remote.JMXServiceURL(URL)
jmxsoc=javax.management.remote.JMXConnectorFactory.connect(jmxurl,jhash)
connection=jmxsoc.getMBeanServerConnection();
#此调用操作工作正常,因为它不需要任何参数
object='Catalina:type=ThreadPool,name=“http-nio-8080”'
attribute=“hasNegotiableProtocols”
打印(connection.invoke(javax.management.ObjectName(object)、属性、无、无))
#此调用操作需要字符串参数(在本例中为“admin”)
object=“Users:type=UserDatabase,database=UserDatabase”
opt=“findUser”
调用(javax.management.ObjectName(object),opt,'admin',None)

有人能建议如何准确地传递第三和第四个参数吗?我在互联网上搜索了很多,但没有找到一个用Python实现的例子。所有示例都使用“None”和“None”作为第三个和第四个参数。

您试图访问的方法的签名是

Object  invoke(ObjectName name, String operationName, Object[] params, String[] signature)
因此,不接受原始字符串作为第三个参数。必须首先创建对象数组。例如:

args = jpype.JArray(jpype.JObject)(['admin'])
这相当于Java语句

Object[] args = new Object[]{"admin"};
如果您经常调用这种类型的数组,只需创建一次列表类型,然后在需要的地方应用它

JObjectArray = jpype.JArray(jpype.JObject)
...
args = JObjectArray(["admin"])

第四个参数也适用同样的情况,只是需要一个字符串数组
jpype.JArray(jpype.JString)

谢谢Karl。根据您的建议,我做了以下更改:
jarray_arg=jpype.jarray(jpype.JObject)(['admin'])
jsignature=jpype.jarray(jpype.JString)
调用
connection.invoke时(javax.management.ObjectName(object),opt,jarray_arg,jsignature)
,但现在我遇到了另一个错误:connection.invoke(javax.management.ObjectName(object)、opt、jarray_arg、jsignature)jpype.\u jexception.mbeanExceptionPraisable:javax.management.MBeanException:找不到操作findUser。但是Mbean存在。第四个参数不正确。您已将jsignature声明为列表类型而不是实际列表。例如“print(jpype.jarray(jpype.JInt))”告诉您这就是类型“”。如果我想要实际的列表,我会使用“print(jpype.JArray(jpype.JInt)([1,2])”。当然,如果您只想将
null
传递到最后一个参数,请使用
None
。《快速入门指南》将很快与JPype 0.7.0一起发布。很抱歉,我没有java方面的经验。在这种情况下,jsignature应该是什么。我尝试了
jsignature=JPype.JArray(JPype.JString)(['admin'))
但它不起作用?不幸的是,我只能在如何将调用转换为JPype方面提供帮助。至于在JMX中接受哪些参数,我建议先找到一个工作的Java示例。这一Java行的第四个参数的python等价物是什么:
mbeanServerConn.invoke(ObjName,“startManagement”,新对象[0],新字符串[0])