Хотя есть документация о том, как открыть JMX через различные брандмауэры и схемы туннелирования, я как бы хочу противоположного. Я хочу убедиться, что JMX доступен только для локального компьютера. К сожалению, похоже, что параметры управления "из коробки" не позволяют ограничивать порты локальным интерфейсом, а netstat показывает, что они прослушивают любой / все интерфейсы.
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html#gdevf
Должен признать, что меня сбивают с толку уровни косвенного обращения в JMX, реестр RMI, разъемы, адаптеры и т. д.
Я хотел бы просто включить его, а затем туннелировать через SSH, вместо того, чтобы открывать его миру, а затем выполнять сложное и излишнее управление пользователями и настройку безопасности. Было бы неплохо иметь возможность использовать встроенный реестр RMI и не запускать внешний.

Ничего не могу поделать с солнечным способом сделать это. Даже после того, как адаптеры jmx начали поставляться с jdk (я думаю, 6?), Я продолжал использовать mx4j для настройки адаптера с наименьшими усилиями. Запускать http-адаптер mx4j на 127.0.0.1 или на внутреннем интерфейсе - тривиальная задача. Затем SOP должен был использовать ssh с перенаправлением портов или использовать сценарии с командами wget.
К сожалению, в настоящее время это невозможно.
Согласно документации Sun, единственный -Dcom.sun.management.jmxremote должен открывать только локальный порт, в то время как -Dcom.sun.management.jmxremote.port = открывает удаленно доступный порт.
Оба способа открывают дополнительный случайный порт, доступный удаленно.
Я видел -Dcom.sun.management.jmxremote.host =, но, похоже, это не имеет никакого эффекта.
Я пришел к выводу, что нет никакой возможности и использовал локальный брандмауэр для защиты сервера.
Немного запоздалый ответ, но если это все еще проблема для вас (или кого-то еще), я думаю, что это поможет:
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.RMISocketFactory;
import javax.management.MBeanServer;
import javax.management.remote.*;
public class LocalJMXPort {
public static void main(String[] args) {
try {
int port = 12468;
// Create an instance of our own socket factory (see below)
RMISocketFactory factory = new LocalHostSocketFactory();
// Set it as default
RMISocketFactory.setSocketFactory(factory);
// Create our registry
LocateRegistry.createRegistry(port);
// Get the MBeanServer and setup a JMXConnectorServer
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://127.0.0.1:"+port+"/jndi/rmi://127.0.0.1:"+port+"/jmxrmi");
JMXConnectorServer rmiServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
rmiServer.start();
// Say something
System.out.println("Connect your jconsole to localhost:"+port+". Press a key to exit");
// Wait for a key press
int in = System.in.read();
//Exit
System.out.println("Exiting");
System.exit(0);
} catch(Exception ex) {
ex.printStackTrace();
}
}
static private class LocalHostSocketFactory extends RMISocketFactory {
public ServerSocket createServerSocket(int port) throws IOException {
ServerSocket ret = new ServerSocket();
ret.bind(new InetSocketAddress("localhost", port));
return ret;
}
public Socket createSocket(String host, int port) throws IOException {
return new Socket(host, port);
}
}
}
Я просто собрал его, и, возможно, я сделал что-то действительно глупое, потому что моей единственной целью было привязать его к localhost: port вместо *: port, и эта часть, похоже, работает.
Не стесняйтесь комментировать, если есть вещи, которые можно улучшить или это просто глупо.
Если вы осуществляете доступ с локального хоста, то в этом случае можно делать то, что делают JConsole и JVisualVM, а именно использовать Attach API для поиска локального адреса сервера (что вы получите, если запустите с - Dcom.sun.management.jmxremote, но не -Dcom.sun.management.jmxremote.port = N) и подключитесь к нему. В другом ответе Траид говорит, что даже в этом случае открывается удаленно доступный порт, что было верно в более ранних версиях, но не было так в течение нескольких лет.
Решение Фредрика работает, но его перебор. Вам нужно только определить RMIServerSocketFactory, а не RMISocketFactory (который определяет как клиент, так и сервер). Это избавляет от необходимости специально настраивать клиента. Код в http://vafer.org/blog/20061010091658 мне кажется правильным.
«Готовое» управление, построенное с использованием таких свойств командной строки, как -Dcom.sun.management.jmxremote, может увести вас так далеко, прежде чем вам понадобится начать программирование с помощью самого JMX API. Как правило, мы неохотно превращали стандартное управление в полноценный параллельный API, поэтому существуют проблемы, подобные этой, которые для него недоступны. Мы объясняем, как перейти от одного здесь к другому.
Эмонн Макманус, руководитель специализации JMX