TCP server sockets with JavaEE 7

Usually JavaEE applications provide a REST interface to communicate with other systems. Some legacy systems do not support REST and I had the requirement to integrate TCP ServerSockets. It is a bad idea to start a server socket directly in an EJB or to even start a new thread, because this can cause malfunctions in the application server (since they are not managed). With ManagedExecutorService it is possible to get a managed instance.

The socket pool is invoked only once as a singleton and creates all socket listeners on startup. In this example I created two listeners manually.

@Startup
@Singleton
public class SocketPool
{

    @Inject
    private Logger logger;

    @Inject
    private Instance<SocketListener> sockets;

    @Resource
    private ManagedExecutorService mes;

    @PostConstruct
    public void init()
    {
        startSocket(5556);
        startSocket(5557);
    }

    private void startSocket(int port)
    {
        SocketListener listener = this.sockets.get();
        listener.setPort(port);
        this.mes.submit(listener);
    }

    @PreDestroy
    public void stop()
    {
        for (SocketListener socket : this.sockets)
        {
            try
            {
                socket.stop();
            }
            catch (IOException ex)
            {
                this.logger.error(ex.getMessage(), ex);
            }
        }
    }
}

The socket listener binds a single port and forwards incoming connections to the socket connection.

public class SocketListener implements Runnable
{

    @Inject
    private Logger logger;

    @Inject
    private Instance<SocketConnection> handles;

    @Resource
    private ManagedExecutorService mes;

    private int port;

    private ServerSocket serverSocket;

    @Override
    public void run()
    {
        try
        {
            this.logger.info("Start server socket at {}", this.port);
            this.serverSocket = new ServerSocket(this.port);
            while (true)
            {
                SocketConnection connection = this.handles.get();
                connection.setSocket(this.serverSocket.accept());
                this.mes.submit(connection);
            }
        }
        catch (IOException ex)
        {
            this.logger.error(ex.getMessage(), ex);
        }
    }

    public void stop() throws IOException
    {
        this.logger.info("Stop server socket at {}", this.port);
        this.serverSocket.close();
    }

    public int getPort()
    {
        return port;
    }

    public void setPort(int port)
    {
        this.port = port;
    }
}

The socket connection does the actual communication with the client.

public class SocketConnection implements Runnable
{

    @Inject
    private Logger logger;

    private Socket socket;

    public Socket getSocket()
    {
        return socket;
    }

    public void setSocket(Socket socket)
    {
        this.socket = socket;
    }

    @Override
    public void run()
    {
        this.logger.info("Accepting client at {}", this.socket.getPort());
        try
        {
            try (OutputStream output = socket.getOutputStream())
            {
                output.write(
                    ("HTTP/1.1 200 OK\n\nCurrentTime: " + LocalDateTime.now())
                    .getBytes()
                );
            }
        }
        catch (IOException ex)
        {
            this.logger.error(ex.getMessage(), ex);
        }
    }
}
Back