2015-07-17 5 views
3

Я хотел бы подключиться к приложению через JMX удалена, поэтому я создал следующие конфигурации в основном методе:Не удается запустить JMXConnectorServer

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:7890/jmxrmi"); 
Map<String, Object> envConf = new HashMap<>(); 
//My custom authenticator 
envConf.put(JMXConnectorServer.AUTHENTICATOR, new MyAuthenticator(jmxUsername, jmxPassword)); 
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, envConf, mbs); 
cs.start(); 

Вот как я начинаю мое заявление:

java -Dcom.sun.management.jmxremote 
    -Dcom.sun.management.jmxremote.port=7890 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false 
    Main 

Но, кажется, что-то не хватает, и я получаю следующее исключение:

Cannot bind to URL [rmi://localhost:7890/jmxrmi]: javax.naming.NoPermissionException [Root exception is java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.AccessException: Cannot modify this registry] 
java.io.IOException: Cannot bind to URL [rmi://localhost:7890/jmxrmi]: javax.naming.NoPermissionException [Root exception is java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.AccessException: Cannot modify this registry] 
    at javax.management.remote.rmi.RMIConnectorServer.newIOException(RMIConnectorServer.java:827) 
    at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:432) 
    at test.jms.Main.start(JmxModule.java:35) 
Caused by: javax.naming.NoPermissionException [Root exception is java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.AccessException: Cannot modify this registry] 
    at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:147) 
    at com.sun.jndi.toolkit.url.GenericURLContext.bind(GenericURLContext.java:228) 
    at javax.naming.InitialContext.bind(InitialContext.java:425) 
    at javax.management.remote.rmi.RMIConnectorServer.bind(RMIConnectorServer.java:644) 
    at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:427) 
    ... 4 more 
Caused by: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.AccessException: Cannot modify this registry 
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:420) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268) 
    at sun.rmi.transport.Transport$1.run(Transport.java:200) 
    at sun.rmi.transport.Transport$1.run(Transport.java:197) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(TCPTransport.java:683) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$13/8098086.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    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:379) 
    at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source) 
    at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:141) 
    ... 8 more 
Caused by: java.rmi.AccessException: Cannot modify this registry 
    at sun.management.jmxremote.SingleEntryRegistry.bind(SingleEntryRegistry.java:76) 
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) 
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:410) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268) 
    at sun.rmi.transport.Transport$1.run(Transport.java:200) 
    at sun.rmi.transport.Transport$1.run(Transport.java:197) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(TCPTransport.java:683) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$13/8098086.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

могли бы вы ро меня, где я ошибаюсь?

ответ

2

Проблема заключалась в том, что у меня не было RMI работает в реестре, так просто запустив эту команду в консоли:

rmiregistry 

или добавив следующую строку кода перед началом сервера:

LocateRegistry.createRegistry(1099); 

решает проблему.

+1

как запустить rmiregistry или где вы добавили эту строку кода? – aysegulP

2

запускающим приложения с помощью Java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port = 7890 -Dcom.sun.management.jmxremote.authenticate = ложь -Dcom. sun.management.jmxremote.ssl = false Главное

вы начинаете разъем RMI JMX по умолчанию на порту 7890. И вы пытаетесь запустить пользовательский разъем на том же порту, и он не работает.

Если вы собираетесь использовать свой собственный экземпляр соединителя, вы можете спокойно опустить все -Dcom.sun.management.jmxremote. *.

+0

В этом случае у меня есть еще одно исключение: 'Не может связываться с URL [RMI: // локальный: 7890/jmxrmi]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: соединение отказалось от хоста: localhost; вложенное исключение: \t java.net.ConnectException: Connection failed: connect] '. Порт не закрыт и не заблокирован брандмауэром –

+1

Обычно люди должны использовать это решение. Вы не должны запускать сервер JMX самостоятельно. Однако, если вам нужна какая-то настройка и нужно запустить ее самостоятельно, проверьте Олесский или мой ответ. – joseph

0

Ниже приведен минимальный рабочий пример для JDK 1.8 простиралась от https://docs.oracle.com/cd/E19698-01/816-7609/6mdjrf86t/index.html#security-ex-37 и https://docs.oracle.com/javase/8/docs/technotes/guides/jmx/tutorial/security.html#wp997065

Ключевые пропущенные шаги из кода в звеньях и принятых ответов являются:

  1. LocateReigstry.createRegistry (порт)
  2. Thread.sleep() loop, чтобы гарантировать, что приложение не отключится.
  3. Ответ не описывает MyAuthenticator. Мой ответ использует аутентификатор по умолчанию, который ожидает пути к файлам доступа и пароля.

Рабочий код Main.java:

import javax.management.MBeanServer; 
import javax.management.remote.JMXConnectorServer; 
import javax.management.remote.JMXConnectorServerFactory; 
import javax.management.remote.JMXServiceURL; 

import java.lang.management.ManagementFactory; 
import java.rmi.registry.LocateRegistry; 
import java.util.*; 

public class Main { 

    public static void main(String[] args) throws Exception { 
     if(args.length != 2) { 
      throw new IllegalArgumentException("Main <port> <path suffix>" 
          + "\nservice:jmx:rmi:///jndi/rmi://localhost:<port>/<pathsuffix>" 
          ); 
     } 

     int port = Integer.parseInt(args[0]); 
     String pathSuffix = args[1]; 

     LocateRegistry.createRegistry(port); 

     MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
     JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://0.0.0.0:" + port + "/" + pathSuffix); 

     Map<String, Object> envConf = new HashMap<>(); 
     envConf.put("jmx.remote.x.password.file", "password.properties"); 
     envConf.put("jmx.remote.x.access.file", "access.properties"); 

     JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, envConf, mbs); 
     cs.start(); 

     while(true) { 
      Thread.sleep(1000); 
     } 
    } 

} 

Содержание jmx.remote.x.access.file:

admin readwrite 

Содержание jmx.remote.x.password.Файл:

admin password 

я выполнил код с мавена использованием (при условии, 8474 доступен):

javac Main.java 
java Main 8474 jmxrmi 
Смежные вопросы