Home > other >  Why Docker (Java Server-Clients) doesn`t work?
Why Docker (Java Server-Clients) doesn`t work?

Time:12-11

I am learning Docker now. And i have faced with a problem: I have been practiced Docker Compose and got a problem with creating containers. The task: There is a Server (Java). The server is very simple. It is just waiting messages from clients and printing them. There are not any threads or something like that. It is not what this app about. The code of the server:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

class Server {
    public static void main(String[] args) throws IOException {
        System.out.println("Server was started!");
        try (ServerSocket serverSocket = new ServerSocket(8899)) {
            while (true) {
                try (Socket client = serverSocket.accept()) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
                    String line = reader.readLine();
                    System.out.println(client.getInetAddress().getHostAddress()   " - "   line);
                } catch (Exception e) {
                    System.out.println("Dops");
                }
            }
        }
    }
}

There are two clients. Also Java language. They are also very simple:

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;


class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
           
        
        String ip = "app_server";
        while (true){
        try (Socket socket = new Socket(ip, 8899)) {
            System.out.println("An attempt...");
            Thread.sleep(10000);
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String message = "Hello from client_1\n";
            writer.write(message);
            writer.flush();
            System.out.println("The package was sent!");
        }
        }
        
    }
}

The second client is totaly the same, but the message is "Hello from client_2\n".

So the idea is to create 3 containers (Server, Client#1, Client#2). And clients have to send a message to the server every 10 seconds. I have tried that on my computer and everithing was fine. It worked perfectly. But I used definite IP 192.168.7.121 in Client app code.

So I created folders:

enter image description here

Dockerfile from Client 1:

FROM openjdk:11

WORKDIR /app_client1

COPY . .

RUN javac Client.java

CMD [ "java", "Client" ]

Dockerfile from Client 2:

FROM openjdk:11

WORKDIR /app_client2

COPY . .

RUN javac Client.java

CMD [ "java", "Client" ]

Docker file from Server

FROM openjdk:11

WORKDIR /app_server

COPY . .

RUN javac Server.java

CMD [ "java", "Server" ]

docker-compose:

version: '3'

services:
  app_server:
    build: ./app_server
  app_client1:
    build: ./app_client1  
  app_client2:
    build: ./app_client2 

And after i had typed the comand "docker-compose up" to terminal, a got this:

PS D:\it\dockerNet\docker-compose-app> docker-compose up
[ ] Running 3/3
 - Container docker-compose-app-app_server-1   Cr...                                             0.6s
 - Container docker-compose-app-app_client2-1  C...                                              0.6s
 - Container docker-compose-app-app_client1-1  C...                                              0.6s
Attaching to docker-compose-app-app_client1-1, docker-compose-app-app_client2-1, docker-compose-app-app_server-1
docker-compose-app-app_client1-1  | Exception in thread "main" java.net.ConnectException: Connection refused (Connection refused)
docker-compose-app-app_client1-1  |     at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
docker-compose-app-app_client1-1  |     at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
docker-compose-app-app_client1-1  |     at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
docker-compose-app-app_client1-1  |     at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
docker-compose-app-app_client1-1  |     at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.connect(Socket.java:609)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.connect(Socket.java:558)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.<init>(Socket.java:454)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.<init>(Socket.java:231)
docker-compose-app-app_client1-1  |     at Client.main(Client.java:15)
docker-compose-app-app_server-1   | /bin/sh: 1: [java,: not found
docker-compose-app-app_client1-1 exited with code 1
docker-compose-app-app_server-1 exited with code 127
docker-compose-app-app_client2-1  | Exception in thread "main" java.net.NoRouteToHostException: No route to host (Host unreachable)
docker-compose-app-app_client2-1  |     at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
docker-compose-app-app_client2-1  |     at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
docker-compose-app-app_client2-1  |     at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
docker-compose-app-app_client2-1  |     at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
docker-compose-app-app_client2-1  |     at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.connect(Socket.java:609)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.connect(Socket.java:558)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.<init>(Socket.java:454)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.<init>(Socket.java:231)
docker-compose-app-app_client2-1  |     at Client.main(Client.java:15)
docker-compose-app-app_client2-1 exited with code 1

And now there are two questions:

  1. Can I change Server IP address by the service name "app_server". Regarding youtube tutorials it is probably possible. If I can`t use that How I suposse to know IP address of the Server before containers creating?

  2. I do not understand why i can not create containers. Where is mistake and what is wrong? What I have done wrong?

I will be very gratefull for you help!


update:

According to advice in comments bellow, I changed code in both Clients to avoid possible exceptions. Now they look like:

import java.io.IOException;


class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println("TEST");
        
    }
}

But I still have error:

PS D:\it\dockerNet\docker-compose-app> docker-compose up
[ ] Running 3/0
 - Container docker-compose-app-app_client2-1  C...                                              0.0s 
 - Container docker-compose-app-app_server-1   Cr...                                             0.0s 
 - Container docker-compose-app-app_client1-1  C...                                              0.0s 
Attaching to docker-compose-app-app_client1-1, docker-compose-app-app_client2-1, docker-compose-app-app_server-1
docker-compose-app-app_server-1   | /bin/sh: 1: [java,: not found
docker-compose-app-app_server-1 exited with code 127
docker-compose-app-app_client2-1  | Exception in thread "main" java.net.NoRouteToHostException: No route to host (Host unreachable)
docker-compose-app-app_client1-1  | Exception in thread "main" java.net.NoRouteToHostException: No route to host (Host unreachable)
docker-compose-app-app_client2-1  |     at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
docker-compose-app-app_client1-1  |     at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
docker-compose-app-app_client2-1  |     at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
docker-compose-app-app_client1-1  |     at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412)
docker-compose-app-app_client2-1  |     at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
docker-compose-app-app_client1-1  |     at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255)
docker-compose-app-app_client2-1  |     at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
docker-compose-app-app_client1-1  |     at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237)
docker-compose-app-app_client2-1  |     at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
docker-compose-app-app_client1-1  |     at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.connect(Socket.java:609)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.connect(Socket.java:609)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.connect(Socket.java:558)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.connect(Socket.java:558)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.<init>(Socket.java:454)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.<init>(Socket.java:454)
docker-compose-app-app_client2-1  |     at java.base/java.net.Socket.<init>(Socket.java:231)
docker-compose-app-app_client1-1  |     at java.base/java.net.Socket.<init>(Socket.java:231)
docker-compose-app-app_client2-1  |     at Client.main(Client.java:15)
docker-compose-app-app_client1-1  |     at Client.main(Client.java:15)
docker-compose-app-app_client1-1 exited with code 1
docker-compose-app-app_client2-1 exited with code 1

CodePudding user response:

SERVER - MYSERVER.java

package org.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class MYSERVER {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.out.println("Server was started!");
        try (ServerSocket serverSocket = new ServerSocket(8899)) {
            while (true) {
                try (Socket client = serverSocket.accept()) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
                    String line = reader.readLine();
                    System.out.println(client.getInetAddress().getHostAddress()   " - "   line);
                } catch (Exception e) {
                    System.out.println("Dops");
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

CLIENT - MYCLIENT.java

package org.example;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Calendar;

public class MYCLIENT {
    public static void main(String[] args)  {
        System.out.println("Hello world!");
        String ip = "localhost";
        if (args.length > 0) ip= args[0];
        System.out.println("ip=" MYCLIENT.javaip);
        int no = 1;
        if (args.length > 1) no= Integer.parseInt(args[1]);
        String whoami="client #" no;
        System.out.println("whoami=" whoami);
        while (true){
            try (Socket socket = new Socket(ip, 8899)) {
                System.out.println("An attempt...");
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                String message = "Hello from " whoami " at "  Calendar.getInstance().getTime()  "\n";
                writer.write(message);
                writer.flush();
                System.out.println("The package was sent!");
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(10000);
            }catch (InterruptedException e) {
                 //do nothing
            }
        }
    }
}

BUILD JAVA TO EXECUTE JAR

  • MYCLIENT-1.0-SNAPSHOT.jar
  • MYSERVER-1.0-SNAPSHOT.jar

HOST TEST

  • Open Terminal 1: java -jar MYSERVER-1.0-SNAPSHOT.jar
  • Open Terminal 2: java -jar MYCLIENT-1.0-SNAPSHOT.jar localhost 1
  • Open Terminal 3: java -jar MYCLIENT-1.0-SNAPSHOT.jar localhost 2
  • Open Terminal 4: java -jar MYCLIENT-1.0-SNAPSHOT.jar localhost 3

MY_SERVER_CLIENT

├── docker-compose.yml
├── MYCLIENT
│   ├── Dockerfile
│   └── MYCLIENT-1.0-SNAPSHOT.jar
└── MYSERVER
    ├── Dockerfile
    └── MYSERVER-1.0-SNAPSHOT.jar

MYSERVER - Dockerfile

FROM eclipse-temurin:17.0.5_8-jre-ubi9-minimal
EXPOSE 8899
WORKDIR /app
COPY MYSERVER-1.0-SNAPSHOT.jar /app/app.jar
ENTRYPOINT ["java","-jar", "app.jar"]

MYSERVER - build command

docker build -t demoserver:1.0.0 .
       
docker tag demoserver:1.0.0 demoserver:latest

MYCLIENT - Dockerfile

FROM eclipse-temurin:17.0.5_8-jre-ubi9-minimal
WORKDIR /app
COPY MYCLIENT-1.0-SNAPSHOT.jar /app/app.jar
ENTRYPOINT ["java","-jar", "app.jar"]
CMD ["locahost","1"]

MYCLIENT - build command

docker build -t democlient:1.0.0 .
       
docker tag democlient:1.0.0 democlient:latest

TEST

Test Server - demoserver

  • Open terminal 1: docker run -it demoserver
  • Open terminal 2: docker ps
  • terminal 2: docker inspect demoserver-container-id

Get container ip like "IPAddress": "172.17.0.2"

Test Client - client

  • Open terminal 3: docker run -it democlient 172.17.0.2 1
  • Open terminal 4: docker run -it democlient 172.17.0.2 2
  • Open terminal 5: docker run -it democlient 172.17.0.2 3
  • Open terminal 6: docker run -it democlient 172.17.0.2 4

See Terminal 1

FIND

$ docker run -it demoserver
Hello world!
Server was started!
172.17.0.3 - Hello from client #1 at Sun Dec 11 10:07:47 GMT 2022
172.17.0.3 - Hello from client #1 at Sun Dec 11 10:07:57 GMT 2022
172.17.0.4 - Hello from client #2 at Sun Dec 11 10:08:02 GMT 2022
172.17.0.3 - Hello from client #1 at Sun Dec 11 10:08:07 GMT 2022
172.17.0.4 - Hello from client #2 at Sun Dec 11 10:08:12 GMT 2022
172.17.0.3 - Hello from client #1 at Sun Dec 11 10:08:17 GMT 2022
172.17.0.5 - Hello from client #3 at Sun Dec 11 10:08:17 GMT 2022
172.17.0.4 - Hello from client #2 at Sun Dec 11 10:08:22 GMT 2022

Last Step Create docker-compose.yml

docker-compose.yml

version: '3.4'

services:
  demoserver:
    image: demoserver

  democlient1:
    image: democlient
    command: demoserver 1
    depends_on:
      - demoserver

  democlient2:
    image: democlient
    command: demoserver 2
    depends_on:
      - demoserver

  democlient3:
    image: democlient
    command: demoserver 3
    depends_on:
      - demoserver

Run docker compose

  • Open terminal: docker compose up

    $ docker compose up [ ] Running 4/0 ⠿ Container my_server_client-demoserver-1 Created 0.0s ⠿ Container my_server_client-democlient3-1 Created 0.0s ⠿ Container my_server_client-democlient1-1 Created 0.0s ⠿ Container my_server_client-democlient2-1 Created 0.0s Attaching to my_server_client-democlient1-1, my_server_client-democlient2-1, my_server_client-democlient3-1, my_server_client-demoserver-1 my_server_client-demoserver-1 | Hello world! my_server_client-demoserver-1 | Server was started! my_server_client-democlient2-1 | Hello world! my_server_client-democlient2-1 | ip=demoserver my_server_client-democlient2-1 | whoami=client #2 my_server_client-democlient2-1 | An attempt... my_server_client-democlient3-1 | Hello world! my_server_client-democlient3-1 | ip=demoserver my_server_client-democlient1-1 | Hello world! my_server_client-democlient3-1 | whoami=client #3 my_server_client-democlient2-1 | The package was sent! my_server_client-democlient1-1 | ip=demoserver my_server_client-demoserver-1 | 172.18.0.3 - Hello from client #2 at Sun Dec 11 10:29:55 GMT 2022 my_server_client-democlient1-1 | whoami=client #1 my_server_client-democlient3-1 | An attempt... my_server_client-democlient1-1 | An attempt... my_server_client-democlient3-1 | The package was sent! my_server_client-demoserver-1 | 172.18.0.4 - Hello from client #3 at Sun Dec 11 10:29:55 GMT 2022 my_server_client-democlient1-1 | The package was sent! my_server_client-demoserver-1 | 172.18.0.5 - Hello from client #1 at Sun Dec 11 10:29:55 GMT 2022

Run docker compose again

  • Open terminal: docker compose up --scale app_client1=10

DIY

services:
  demoserver:
    image: demoserver

  democlient1:
    image: democlient
  ...

Change image to build yourself.

Do one thing at a time

  • Step 1. test java part, server , client
  • Step 2. package server, client as execute jar
  • Step 3. test it on host, not on docker
  • Step 4. pack server to docker image
  • Step 5. test server use docker image, but test client on host
  • Step 6. pack client to docker image
  • Step 7. test server image and client image
  • Step 8. build docker-compose.yml
  • Step 9. test docker compose

I am used to cutting the problem into many parts, then solving each part, testing each part, and finally combining each part But each part has been tested, so I can know what the message is if an error occurs, which part is wrong, and how to deal with it.

  • Related