Skip to content

Instantly share code, notes, and snippets.

@bademux
Last active May 23, 2021 16:16
Show Gist options
  • Save bademux/f06dba9c23fa2cbf4e746271535ce0ab to your computer and use it in GitHub Desktop.
Save bademux/f06dba9c23fa2cbf4e746271535ce0ab to your computer and use it in GitHub Desktop.
Using java jmx over rmi with remote docker container. MIT licensed :)
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.ContainerNetwork;
import com.github.dockerjava.api.model.ContainerPort;
import lombok.SneakyThrows;
import lombok.experimental.Delegate;
import java.util.*;
/**
* init asap with utils.DockerHackfixRMISocketFactory#init(), then target container run using env var
* JAVA_TOOL_OPTIONS="-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=9001 -Dcom.sun.management.jmxremote.rmi.port=9001"
*/
@Slf4j
final class DockerHackfixRMISocketFactory extends RMISocketFactory {
@Delegate(types = RMIServerSocketFactory.class)
private final RMISocketFactory socketFactory = RMISocketFactory.getDefaultSocketFactory();
@Override
public Socket createSocket(String host, int port) throws IOException {
DockerClientFactory docker = DockerClientFactory.instance();
String dockerHostIpAddress = docker.dockerHostIpAddress();
if (dockerHostIpAddress.equals(host)) {
log.debug("Making initial connection to {}:{}", dockerHostIpAddress, port);
return socketFactory.createSocket(host, port);
}
log.debug("try to translate {}:{} that comes from the jmx server", host, port);
int publicJmxPort = docker.client().listContainersCmd().exec().stream()
.filter(container -> container.getNetworkSettings().getNetworks().values().stream().map(ContainerNetwork::getIpAddress).anyMatch(host::equals))
.map(Container::getPorts)
.flatMap(Stream::of)
.filter(containerPort -> Objects.equals(containerPort.getPrivatePort(), port))
.map(ContainerPort::getPublicPort)
.findFirst()
.orElseThrow(() -> new IllegalStateException("No container found for " + host + ':' + port));
log.debug("connecting to {}:{}", dockerHostIpAddress, publicJmxPort);
return socketFactory.createSocket(dockerHostIpAddress, publicJmxPort);
}
@SneakyThrows
public static void init() {
RMISocketFactory.setSocketFactory(new DockerHackfixRMISocketFactory());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment