简体   繁体   English

通过 Nashorn javascript jjs 的 JMX 连接

[英]JMX connection via Nashorn javascript jjs

I am writing a script in JavaScript engine that comes with JDK8.我正在用 JDK8 附带的 JavaScript 引擎编写脚本。 This script will use JMX to connect to a remote Java instance.此脚本将使用 JMX 连接到远程 Java 实例。 I am using authentication, but no SSL.我正在使用身份验证,但没有使用 SSL。 The JMX connection is working fine from any JMX client, the problem is in this script JMX 连接在任何 JMX 客户端都可以正常工作,问题出在此脚本中

The output of the script is:脚本的输出是:

[root@testvm ~]# /opt/scripts/jmx-test.jjs
{javax.management.remote.JMXConnector.CREDENTIALS=[Ljava.lang.String;@679b62af}
Exception in thread "main" java.lang.SecurityException: Authentication failed! Credentials required
        at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticationFailure(JMXPluggableAuthenticator.java:211)
        at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticate(JMXPluggableAuthenticator.java:163)
        at sun.management.jmxremote.ConnectorBootstrap$AccessFileCheckerAuthenticator.authenticate(ConnectorBootstrap.java:219)
        at javax.management.remote.rmi.RMIServerImpl.doNewClient(RMIServerImpl.java:232)
        at javax.management.remote.rmi.RMIServerImpl.newClient(RMIServerImpl.java:199)
        at sun.reflect.GeneratedMethodAccessor18147.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
        at sun.rmi.transport.Transport$1.run(Transport.java:177)
        at sun.rmi.transport.Transport$1.run(Transport.java:174)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
        at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)
        at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2404)
        at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:308)
        at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:270)
        at jdk.nashorn.internal.scripts.Script$jmx_test_jjs.runScript(/opt/scripts/jmx-test.jjs:14)
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:535)
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:209)
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
        at jdk.nashorn.tools.Shell.apply(Shell.java:383)
        at jdk.nashorn.tools.Shell.runScripts(Shell.java:312)
        at jdk.nashorn.tools.Shell.run(Shell.java:168)
        at jdk.nashorn.tools.Shell.main(Shell.java:132)
        at jdk.nashorn.tools.Shell.main(Shell.java:111)

Here is the script:这是脚本:

#! /usr/java/jdk1.8.0_25/bin/jjs
host="remotehost"
port=7091
serviceURL = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"
url = new javax.management.remote.JMXServiceURL(serviceURL);
stringArrayType = Java.type("java.lang.String[]")
credentials = new stringArrayType(2)
credentials[0]="user"
credentials[1]="password1"
HashMapType = Java.type("java.util.HashMap")
environment = new HashMapType()
environment.put("javax.management.remote.JMXConnector.CREDENTIALS",credentials)
print(environment)
connector = javax.management.remote.JMXConnectorFactory.connect(url,environment)

It seems that credentials become null .似乎凭据变为null See: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java#162请参阅: http : //grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java#162

The problem is that I do not know how to properly send the environment to the javax.management.remote.JMXConnectorFactory.connect()问题是我不知道如何正确地将环境发送到 javax.management.remote.JMXConnectorFactory.connect()

Edit : With the answer of @Nicholas, the script now works.编辑:有了@Nicholas 的回答,脚本现在可以工作了。 Here is the full example:这是完整的示例:

#! /usr/java/jdk1.8.0_25/bin/jjs
host="remotehost"
port=7091
serviceURL = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"
url = new javax.management.remote.JMXServiceURL(serviceURL);
stringArrayType = Java.type("java.lang.String[]")
credentials = new stringArrayType(2)
credentials[0]="user"
credentials[1]="password1"
HashMapType = Java.type("java.util.HashMap")
environment = new HashMapType()
environment.put("jmx.remote.credentials",credentials)
connector = javax.management.remote.JMXConnectorFactory.connect(url,environment)
mbeanServerConnection=connector.getMBeanServerConnection()
ObjectNameType = Java.type("javax.management.ObjectName")

objectName = new ObjectNameType('Catalina:type=Connector,port=8009,address="tomcat.example.org"')
print(mbeanServerConnection.getAttribute(objectName, "proxyName"))

objectName = new ObjectNameType('java.lang:type=Memory')
#print(mbeanServerConnection.getAttribute(objectName, "HeapMemoryUsage"))
print('HeapMemoryUsage, used = ' + mbeanServerConnection.getAttribute(objectName, "HeapMemoryUsage").get('used'))

Take a look at this line of your script:看看你脚本的这一行:

environment.put("javax.management.remote.JMXConnector.CREDENTIALS",credentials)

The API defines the key of the map entry as the constant javax.management.remote.JMXConnector.CREDENTIALS but the value of the constant is "jmx.remote.credentials" . API定义的映射项作为恒定的关键javax.management.remote.JMXConnector.CREDENTIALS但所述恒定的“jmx.remote.credentials”

Therefore, try changing that line to:因此,尝试将该行更改为:

environment.put("jmx.remote.credentials",credentials)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM