Соединение JMX не воспроизводится при запуске JMXConnectorFactory.connect
Нужна ваша помощь, чтобы понять, почему я не могу подключиться из клиентского приложения к серверному приложению с помощью JMX. У меня есть серверное приложение, которое запускает сервер JMX Bean, и клиент, который пытается подключиться к этому серверу с помощью JMX. оба приложения рушатся на локальной машине в Windows. Jconsole работает нормально, и я могу подключиться к ней к серверу. Но при запуске клиента он "застревает" на линии:
JMXConnector jmxConnector = JMXConnectorFactory.connect(url, null);
Код инициализации JMX-сервера на стороне приложения:
MyClass mc = new MyClass ();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName obj = new ObjectName("JMX:name=MyClassJmx");
mbs.registerMBean(mc, obj);
Параметры JMX Server на стороне приложения:
-Dcom.sun.management.jmxremote.port=10090
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Мое клиентское соединение с кодом приложения:
final JMXServiceURL url = new JMXServiceURL("service:jmx:jmxmp://127.0.0.1:10090");
JMXConnector jmxConnector = JMXConnectorFactory.connect(url, null);
jmxConnector.connect();
Примечание, используя
сервис:jmx:rmi:///jndi/rmi://:10090/jmxrmi
работает.
1 ответ
Соединитель протокола обмена сообщениями JMX (JMXMP) представляет собой конфигурацию универсального соединителя, в котором транспортный протокол основан на TCP, а упаковка объектов - это собственная сериализация Java. Безопасность более продвинутая, чем для разъема RMI. Безопасность основана на Java Secure Socket Extension (JSSE), Java Authentication and Authorization Service (JAAS) и Simple Authentication and Security Layer (SASL).
Общий соединитель и его конфигурация JMXMP не являются обязательными, что означает, что они не всегда включаются в реализацию JMX Remote API. Платформа J2SE не включает дополнительный универсальный соединитель.
Примечание. Если вы хотите использовать коннектор JMXMP, загрузите справочную реализацию JSR 160 с http://java.sun.com/products/JavaManagement/download.html и добавьте файл jmxremote_optional.jar в путь к классам.
Вы включили
jmxremote_optional.jar
файл на вашем сервере и пути к классам клиента?
У меня нет предыдущего опыта работы с подходом JMXMP Connector, я следил за документацией JMX и пытался проверить, написав следующий пример, и он работает.
Интерфейс JMX MBean
SystemConfigMBean.java
package jmx.learning;
public interface SystemConfigMBean {
public void setThreadCount(int noOfThreads);
public int getThreadCount();
public void setSchemaName(String schemaName);
public String getSchemaName();
// any method starting with get and set are considered
// as attributes getter and setter methods, so I am
// using do* for operation.
public String doConfig();
}
Класс для реализации интерфейса JMX MBean
SystemConfig.java
package jmx.learning;
public class SystemConfig implements SystemConfigMBean {
private int threadCount;
private String schemaName;
public SystemConfig(int numThreads, String schema){
this.threadCount=numThreads;
this.schemaName=schema;
}
@Override
public void setThreadCount(int noOfThreads) {
this.threadCount=noOfThreads;
}
@Override
public int getThreadCount() {
return this.threadCount;
}
@Override
public void setSchemaName(String schemaName) {
this.schemaName=schemaName;
}
@Override
public String getSchemaName() {
return this.schemaName;
}
@Override
public String doConfig(){
return "No of Threads="+this.threadCount+" and DB Schema Name="+this.schemaName;
}
}
Создание и регистрация MBean на сервере MBean с помощью соединителя JMXMP
SystemConfigManagement.java
package jmx.learning;
import java.io.IOException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class SystemConfigManagement {
private static final int DEFAULT_NO_THREADS = 10;
private static final String DEFAULT_SCHEMA = "default";
public static void main(String[] args) throws MalformedObjectNameException,
InterruptedException, InstanceAlreadyExistsException,
MBeanRegistrationException, NotCompliantMBeanException, IOException {
// Instantiate the MBean server
MBeanServer mbs = MBeanServerFactory.createMBeanServer();
// Create a JMXMP connector server
JMXServiceURL url = new JMXServiceURL("jmxmp", null, 5555);
JMXConnectorServer cs = JMXConnectorServerFactory
.newJMXConnectorServer(url, null, mbs);
cs.start();
// register the MBean
SystemConfig mBean = new SystemConfig(DEFAULT_NO_THREADS,
DEFAULT_SCHEMA);
ObjectName name = new ObjectName("jmx.learning:type=SystemConfig");
mbs.registerMBean(mBean, name);
do {
Thread.sleep(3000);
System.out.println("Thread Count=" + mBean.getThreadCount()
+ " Schema Name=" + mBean.getSchemaName());
} while (mBean.getThreadCount() != 0);
}
}
Клиент коннектора JMXMP
SystemConfigManagementClient.java
package jmx.learning;
import java.io.IOException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class SystemConfigManagementClient {
public static void main(String[] args) {
JMXConnector jmxc = null;
try {
// Create a JMXMP connector client
System.out.println("\nCreate a JMXMP connector client");
JMXServiceURL url = new JMXServiceURL(
"service:jmx:jmxmp://localhost:5555");
jmxc = JMXConnectorFactory.connect(url, null);
// get MBeanServerConnection
MBeanServerConnection serverConn = jmxc.getMBeanServerConnection();
ObjectName objectName = new ObjectName(
"jmx.learning:type=SystemConfig");
// Executing doConfig() method
String value = (String) serverConn.invoke(objectName, "doConfig",
new Object[] {}, new String[] {});
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jmxc != null) {
try {
jmxc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ПРИМЕЧАНИЕ: я скачал
jmxremote_optional.jar
файл и хранится в пути к классам проекта.
Исполнение:
Выход сервера:
d:\Java\jdk1.8.0_261\bin\java.exe -cp .;d:\External_Library\jmxremote_optional.jar jmx.learning.SystemConfigManagement
Thread Count=10 Schema Name=default
Thread Count=10 Schema Name=default
Выход клиента:
d:\Java\jdk1.8.0_261\bin\java.exe -cp .;d:\External_Library\jmxremote_optional.jar jmx.learning.SystemConfigManagementClient
Create a JMXMP connector client
No of Threads=10 and DB Schema Name=default
Я не уверен в коде сервера, который вы написали, похоже, этот код ожидает RMIConnector. Таким образом, от Клиента работает попытка подключения с использованием RMI-коннектора Java Remote Method Protocol (JRMP).
Даже вы прошли собственность
-Dcom.sun.management.jmxremote.port=portNum
Это свойство указывает, что portNum - это номер порта, через который вы хотите разрешить соединения JMX RMI.
ПРИМЕЧАНИЕ. В демонстрационных целях я не показал элементы безопасной обработки, в реальном коде они должны быть на месте.