Communication Between Linked Docker Containers With Java EE

Docker container to container communication requires either the use of legacy docker links or links in user defined frameworks.

The IP address is dynamically assigned by the docker daemon to the containers and is not known at build time. In a legacy-link scenario the IP address and port-number has to be extracted from static OS environment variables, and in the user-defined networks case the container name, or its alias, can be directly used as hostname. Also in the user-defined scenario there is no additional port-lookup needed. The exposed port can be used without any translation.

For the extraction of legacy links the IP address and the port have to be resolved using System#getenv:

public interface URIProvider {

    public static String computeURIWithEnvironmentEntries(String linkName, int portNumber) {
        String stringifiedPort = String.valueOf(portNumber);
        String portKey = computePortKey(linkName, stringifiedPort);
        String addressKey = computeAddressKey(linkName, stringifiedPort);
        return "http://" + getEnvironmentVariable(addressKey) + ":" + getEnvironmentVariable(portKey);
    static String getEnvironmentVariable(String key) {
        String variable = System.getenv(key);
        if (variable == null) {
            throw new IllegalStateException("No environment variable found for: " + key);
        return variable;

    static String computeKeyPrefix(String linkName, String portNumber) {
        String upperLink = linkName.toUpperCase();
        return upperLink + "_PORT_" + portNumber + "_TCP_";

    static String computePortKey(String linkName, String portNumber) {
        return computeKeyPrefix(linkName, portNumber) + "PORT";

    static String computeAddressKey(String linkName, String portNumber) {
        return computeKeyPrefix(linkName, portNumber) + "ADDR";

In the user-defined network scenario the link and port can be directly used:

  public static String computeUri(String linkName, int portNumber, String resource) {
        return "http://" + linkName + ":" + portNumber + resource;

    public static String computeUri(String linkName, int portNumber) {
        return computeUri(linkName, portNumber, "");

In Java EE context we can introduce more convenience with a qualifier:

@Target({ElementType.FIELD, ElementType.METHOD})
public @interface LegacyLink {

    String name() default "";

    int portNumber() default 8080;

    String path() default "";

...and combine it with some conventions:

    public String exposeLegacyLink(InjectionPoint ip) {
        Annotated field = ip.getAnnotated();
        LegacyLink link = field.getAnnotation(LegacyLink.class);
        String linkName =;
        if (linkName.isEmpty()) {
            linkName = ip.getMember().getName().toUpperCase();
        int portNumber = link.portNumber();
        String resource = link.path();
        if (resource.isEmpty()) {
            return URIProvider.computeURIWithEnvironmentEntries(linkName, portNumber);
        } else {
            return URIProvider.computeURIWithEnvironmentEntries(linkName, portNumber, resource);

    public WebTarget exposeLegacyLinkWebTarget(InjectionPoint ip) {
        Client client = ClientBuilder.newClient();

...what makes the WebTarget conveniently injectable:

    @LegacyLink(portNumber = 8080, path = "/hugo")
    String ping;

The servicelink utility is already available in maven-central:


See also: for documentation.

I got the idea for this utility in an undisclosed location -- the origin name was: urimator :-).

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home:

NEW online workshop: Web Components training (online)

Airport MUC workshops: Java EE 8, Java 9: Bootstrap, Effective, Architectures, Single Page Apps, Progressive Web Apps, HTML 5, ES 6, CSS 3 and Microservices

Podcast: and newsletter:

A book about rethinking Java EE Patterns


Hi Adam!

Maybe I didn't understand this correctly, but /etc/hosts is updated (at least in my docker version) everytime a container is started, so that the alias given by --link <container>:<alias> can successfully be resolved. And the documentation says that the environment variables are only updated on first start (as far as I understood).


Posted by Stefan on February 22, 2016 at 02:29 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
Online Workshops
...the last 150 posts
...the last 10 comments