Better Javadoc and minor clean up.
diff --git a/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java b/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
index ae1c592..51c071c 100644
--- a/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
+++ b/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
@@ -1,396 +1,393 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.server;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.OptionalDataException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.validators.PositiveInteger;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.core.parser.ParseException;
-import org.apache.logging.log4j.core.util.BasicCommandLineArguments;
-import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.core.util.Log4jThread;
-import org.apache.logging.log4j.message.EntryMessage;
-
-/**
- * Listens for Log4j events on a TCP server socket and passes them on to Log4j.
- *
- * @param <T>
- * The kind of input stream read
- * @see #main(String[])
- */
-public class TcpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
-
- protected static class CommandLineArguments extends AbstractSocketServer.CommandLineArguments {
-
- @Parameter(names = { "--backlog",
- "-b" }, validateWith = PositiveInteger.class, description = "Server socket backlog.")
- // Same default as ServerSocket
- private int backlog = 50;
-
- int getBacklog() {
- return backlog;
- }
-
- void setBacklog(final int backlog) {
- this.backlog = backlog;
- }
-
- }
-
- /**
- * Thread that processes the events.
- */
- private class SocketHandler extends Log4jThread {
-
- private final T inputStream;
- private final Socket socket;
-
- private volatile boolean shutdown = false;
-
- public SocketHandler(final Socket socket) throws IOException {
- this.socket = socket;
- this.inputStream = logEventInput.wrapStream(socket.getInputStream());
- }
-
- @Override
- public void run() {
- final EntryMessage entry = logger.traceEntry();
- boolean closed = false;
- try {
- try {
- while (!shutdown) {
- logEventInput.logEvents(inputStream, TcpSocketServer.this);
- }
- } catch (final EOFException e) {
- closed = true;
- } catch (final OptionalDataException e) {
- logger.error("OptionalDataException eof=" + e.eof + " length=" + e.length, e);
- } catch (final IOException e) {
- logger.error("IOException encountered while reading from socket", e);
- } catch (ParseException e) {
- logger.error("ParseException encountered while reading from socket", e);
- }
- if (!closed) {
- Closer.closeSilently(inputStream);
- }
- } finally {
- handlers.remove(Long.valueOf(getId()));
- }
- logger.traceExit(entry);
- }
-
- public void shutdown() {
- this.shutdown = true;
- if (socket != null) {
- Closer.closeSilently(socket);
- }
- interrupt();
- }
- }
-
- /**
- * Creates a socket server that reads JSON log events.
- *
- * @param port
- * The server socket port.
- * @return a new a socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- */
- public static TcpSocketServer<InputStream> createJsonSocketServer(final int port) throws IOException {
- LOGGER.entry("createJsonSocketServer", port);
- final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new JsonInputStreamLogEventBridge());
- return LOGGER.exit(socketServer);
- }
-
- /**
- * Creates a socket server that reads JSON log events.
- *
- * @param port
- * The server socket port.
- * @param backlog
- * The server socket backlog.
- * @param localBindAddress
- * The local InetAddress the server will bind to
- * @return a new a socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- * @since 2.9
- */
- public static TcpSocketServer<InputStream> createJsonSocketServer(final int port, final int backlog,
- final InetAddress localBindAddress) throws IOException {
- LOGGER.entry("createJsonSocketServer", port, backlog, localBindAddress);
- final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
- new JsonInputStreamLogEventBridge());
- return LOGGER.exit(socketServer);
- }
-
- /**
- * Creates a socket server that reads serialized log events.
- *
- * @param port
- * The server socket port.
- * @return a new a socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- */
- public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port) throws IOException {
- LOGGER.entry(port);
- final TcpSocketServer<ObjectInputStream> socketServer = new TcpSocketServer<>(port, new ObjectInputStreamLogEventBridge());
- return LOGGER.exit(socketServer);
- }
-
- /**
- * Creates a socket server that reads serialized log events.
- *
- * @param port
- * The server socket port.
- * @param backlog
- * The server socket backlog.
- * @param localBindAddress
- * The local InetAddress the server will bind to
- * @return a new a socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- * @since 2.7
- */
- public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port, final int backlog,
- final InetAddress localBindAddress) throws IOException {
- return createSerializedSocketServer(port, backlog, localBindAddress, Collections.<String>emptyList());
- }
-
- /**
- * Creates a socket server that reads serialized log events.
- *
- * @param port
- * The server socket port.
- * @param backlog
- * The server socket backlog.
- * @param localBindAddress
- * The local InetAddress the server will bind to
- * @param allowedClasses additional class names to allow for deserialization
- * @return a new a socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- * @since 2.8.2
- */
- public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(
- final int port, final int backlog, final InetAddress localBindAddress, final List<String> allowedClasses
- ) throws IOException {
- LOGGER.entry(port);
- final TcpSocketServer<ObjectInputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
- new ObjectInputStreamLogEventBridge(allowedClasses));
- return LOGGER.exit(socketServer);
- }
-
- /**
- * Creates a socket server that reads XML log events.
- *
- * @param port
- * The server socket port.
- * @return a new a socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- */
- public static TcpSocketServer<InputStream> createXmlSocketServer(final int port) throws IOException {
- LOGGER.entry(port);
- final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new XmlInputStreamLogEventBridge());
- return LOGGER.exit(socketServer);
- }
-
- /**
- * Creates a socket server that reads XML log events.
- *
- * @param port
- * The server socket port.
- * @param backlog
- * The server socket backlog.
- * @param localBindAddress
- * The local InetAddress the server will bind to
- * @return a new a socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- * @since 2.9
- */
- public static TcpSocketServer<InputStream> createXmlSocketServer(final int port,
- final int backlog, final InetAddress localBindAddress
- ) throws IOException {
- LOGGER.entry(port);
- final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
- new XmlInputStreamLogEventBridge());
- return LOGGER.exit(socketServer);
- }
-
- /**
- * Main startup for the server. Run with "--help" for to print command line help on the console.
- *
- * @param args
- * The command line arguments.
- * @throws Exception
- * if an error occurs.
- */
- public static void main(final String[] args) throws Exception {
- final CommandLineArguments cla = BasicCommandLineArguments.parseCommandLine(args, TcpSocketServer.class, new CommandLineArguments());
- if (cla.isHelp()) {
- return;
- }
- if (cla.getConfigLocation() != null) {
- ConfigurationFactory.setConfigurationFactory(new ServerConfigurationFactory(cla.getConfigLocation()));
- }
- final TcpSocketServer<InputStream> socketServer = TcpSocketServer.createJsonSocketServer(
- cla.getPort(), cla.getBacklog(), cla.getLocalBindAddress());
- final Thread serverThread = socketServer.startNewThread();
- if (cla.isInteractive()) {
- socketServer.awaitTermination(serverThread);
- }
- }
-
- private final ConcurrentMap<Long, SocketHandler> handlers = new ConcurrentHashMap<>();
-
- private final ServerSocket serverSocket;
-
- /**
- * Constructor.
- *
- * @param port
- * The server socket port.
- * @param backlog
- * The server socket backlog.
- * @param localBindAddress
- * The local InetAddress the server will bind to
- * @param logEventInput
- * the log even input
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- * @since 2.7
- */
- @SuppressWarnings("resource")
- public TcpSocketServer(final int port, final int backlog, final InetAddress localBindAddress, final LogEventBridge<T> logEventInput) throws IOException {
- this(port, logEventInput, new ServerSocket(port, backlog, localBindAddress));
- }
-
- /**
- * Constructor.
- *
- * @param port
- * The server socket port
- * @param logEventInput
- * the log even input
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- */
- public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput) throws IOException {
- this(port, logEventInput, extracted(port));
- }
-
- private static ServerSocket extracted(final int port) throws IOException {
- return new ServerSocket(port);
- }
-
- /**
- * Constructor.
- *
- * @param port
- * to listen.
- * @param logEventInput
- * the log even input
- * @param serverSocket
- * the socket server
- * @throws IOException
- * if an I/O error occurs when opening the socket.
- */
- public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput, final ServerSocket serverSocket)
- throws IOException {
- super(port, logEventInput);
- this.serverSocket = serverSocket;
- }
-
- /**
- * Accept incoming events and processes them.
- */
- @Override
- public void run() {
- final EntryMessage entry = logger.traceEntry();
- while (isActive()) {
- if (serverSocket.isClosed()) {
- return;
- }
- try {
- // Accept incoming connections.
- logger.debug("Listening for a connection {}...", serverSocket);
- @SuppressWarnings("resource") // clientSocket is closed during SocketHandler shutdown
- final Socket clientSocket = serverSocket.accept();
- logger.debug("Acepted connection on {}...", serverSocket);
- logger.debug("Socket accepted: {}", clientSocket);
- clientSocket.setSoLinger(true, 0);
-
- // accept() will block until a client connects to the server.
- // If execution reaches this point, then it means that a client
- // socket has been accepted.
-
- final SocketHandler handler = new SocketHandler(clientSocket);
- handlers.put(Long.valueOf(handler.getId()), handler);
- handler.start();
- } catch (final IOException e) {
- if (serverSocket.isClosed()) {
- // OK we're done.
- logger.traceExit(entry);
- return;
- }
- logger.error("Exception encountered on accept. Ignoring. Stack trace :", e);
- }
- }
- for (final Map.Entry<Long, SocketHandler> handlerEntry : handlers.entrySet()) {
- final SocketHandler handler = handlerEntry.getValue();
- handler.shutdown();
- try {
- handler.join();
- } catch (final InterruptedException ignored) {
- // Ignore the exception
- }
- }
- logger.traceExit(entry);
- }
-
- /**
- * Shutdown the server.
- *
- * @throws IOException if the server socket could not be closed
- */
- @Override
- public void shutdown() throws IOException {
- final EntryMessage entry = logger.traceEntry();
- setActive(false);
- //Thread.currentThread().interrupt();
- serverSocket.close();
- logger.traceExit(entry);
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.server;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.OptionalDataException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.validators.PositiveInteger;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.parser.ParseException;
+import org.apache.logging.log4j.core.util.BasicCommandLineArguments;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.core.util.Log4jThread;
+import org.apache.logging.log4j.message.EntryMessage;
+
+/**
+ * Listens for Log4j events on a TCP server socket and passes them on to Log4j.
+ *
+ * @param <T>
+ * The kind of input stream read
+ * @see #main(String[])
+ */
+public class TcpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
+
+ protected static class CommandLineArguments extends AbstractSocketServer.CommandLineArguments {
+
+ @Parameter(names = { "--backlog",
+ "-b" }, validateWith = PositiveInteger.class, description = "Server socket backlog.")
+ // Same default as ServerSocket
+ private int backlog = 50;
+
+ int getBacklog() {
+ return backlog;
+ }
+
+ void setBacklog(final int backlog) {
+ this.backlog = backlog;
+ }
+
+ }
+
+ /**
+ * Thread that processes the events.
+ */
+ private class SocketHandler extends Log4jThread {
+
+ private final T inputStream;
+ private final Socket socket;
+
+ private volatile boolean shutdown = false;
+
+ public SocketHandler(final Socket socket) throws IOException {
+ this.socket = socket;
+ this.inputStream = logEventInput.wrapStream(socket.getInputStream());
+ }
+
+ @Override
+ public void run() {
+ final EntryMessage entry = logger.traceEntry();
+ boolean closed = false;
+ try {
+ try {
+ while (!shutdown) {
+ logEventInput.logEvents(inputStream, TcpSocketServer.this);
+ }
+ } catch (final EOFException e) {
+ closed = true;
+ } catch (final OptionalDataException e) {
+ logger.error("OptionalDataException eof=" + e.eof + " length=" + e.length, e);
+ } catch (final IOException e) {
+ logger.error("IOException encountered while reading from socket", e);
+ } catch (ParseException e) {
+ logger.error("ParseException encountered while reading from socket", e);
+ }
+ if (!closed) {
+ Closer.closeSilently(inputStream);
+ }
+ } finally {
+ handlers.remove(Long.valueOf(getId()));
+ }
+ logger.traceExit(entry);
+ }
+
+ public void shutdown() {
+ this.shutdown = true;
+ if (socket != null) {
+ Closer.closeSilently(socket);
+ }
+ interrupt();
+ }
+ }
+
+ /**
+ * Creates a socket server that reads JSON log events.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @return a new a socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ */
+ public static TcpSocketServer<InputStream> createJsonSocketServer(final int port) throws IOException {
+ LOGGER.entry("createJsonSocketServer", port);
+ final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new JsonInputStreamLogEventBridge());
+ return LOGGER.exit(socketServer);
+ }
+
+ /**
+ * Creates a socket server that reads JSON log events.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @param backlog
+ * The server socket backlog.
+ * @param localBindAddress
+ * The local InetAddress the server will bind to
+ * @return a new a socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ * @since 2.9
+ */
+ public static TcpSocketServer<InputStream> createJsonSocketServer(final int port, final int backlog,
+ final InetAddress localBindAddress) throws IOException {
+ LOGGER.entry("createJsonSocketServer", port, backlog, localBindAddress);
+ final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
+ new JsonInputStreamLogEventBridge());
+ return LOGGER.exit(socketServer);
+ }
+
+ /**
+ * Creates a socket server that reads serialized log events.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @return a new a socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ */
+ public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port) throws IOException {
+ LOGGER.entry(port);
+ final TcpSocketServer<ObjectInputStream> socketServer = new TcpSocketServer<>(port, new ObjectInputStreamLogEventBridge());
+ return LOGGER.exit(socketServer);
+ }
+
+ /**
+ * Creates a socket server that reads serialized log events.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @param backlog
+ * The server socket backlog.
+ * @param localBindAddress
+ * The local InetAddress the server will bind to
+ * @return a new a socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ * @since 2.7
+ */
+ public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port, final int backlog,
+ final InetAddress localBindAddress) throws IOException {
+ return createSerializedSocketServer(port, backlog, localBindAddress, Collections.<String>emptyList());
+ }
+
+ /**
+ * Creates a socket server that reads serialized log events.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @param backlog
+ * The server socket backlog.
+ * @param localBindAddress
+ * The local InetAddress the server will bind to
+ * @param allowedClasses additional class names to allow for deserialization
+ * @return a new a socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ * @since 2.8.2
+ */
+ public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(
+ final int port, final int backlog, final InetAddress localBindAddress, final List<String> allowedClasses
+ ) throws IOException {
+ LOGGER.entry(port);
+ final TcpSocketServer<ObjectInputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
+ new ObjectInputStreamLogEventBridge(allowedClasses));
+ return LOGGER.exit(socketServer);
+ }
+
+ /**
+ * Creates a socket server that reads XML log events.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @return a new a socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ */
+ public static TcpSocketServer<InputStream> createXmlSocketServer(final int port) throws IOException {
+ LOGGER.entry(port);
+ final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, new XmlInputStreamLogEventBridge());
+ return LOGGER.exit(socketServer);
+ }
+
+ /**
+ * Creates a socket server that reads XML log events.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @param backlog
+ * The server socket backlog.
+ * @param localBindAddress
+ * The local InetAddress the server will bind to
+ * @return a new a socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ * @since 2.9
+ */
+ public static TcpSocketServer<InputStream> createXmlSocketServer(final int port,
+ final int backlog, final InetAddress localBindAddress
+ ) throws IOException {
+ LOGGER.entry(port);
+ final TcpSocketServer<InputStream> socketServer = new TcpSocketServer<>(port, backlog, localBindAddress,
+ new XmlInputStreamLogEventBridge());
+ return LOGGER.exit(socketServer);
+ }
+
+ /**
+ * Main startup for the server. Run with "--help" for to print command line help on the console.
+ *
+ * @param args
+ * The command line arguments.
+ * @throws Exception
+ * if an error occurs.
+ */
+ public static void main(final String[] args) throws Exception {
+ final CommandLineArguments cla = BasicCommandLineArguments.parseCommandLine(args, TcpSocketServer.class, new CommandLineArguments());
+ if (cla.isHelp()) {
+ return;
+ }
+ if (cla.getConfigLocation() != null) {
+ ConfigurationFactory.setConfigurationFactory(new ServerConfigurationFactory(cla.getConfigLocation()));
+ }
+ final TcpSocketServer<InputStream> socketServer = TcpSocketServer.createJsonSocketServer(
+ cla.getPort(), cla.getBacklog(), cla.getLocalBindAddress());
+ final Thread serverThread = socketServer.startNewThread();
+ if (cla.isInteractive()) {
+ socketServer.awaitTermination(serverThread);
+ }
+ }
+
+ private final ConcurrentMap<Long, SocketHandler> handlers = new ConcurrentHashMap<>();
+
+ private final ServerSocket serverSocket;
+
+ /**
+ * Constructor.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @param backlog
+ * The server socket backlog.
+ * @param localBindAddress
+ * The local InetAddress the server will bind to
+ * @param logEventInput
+ * the log even input
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ * @since 2.7
+ */
+ @SuppressWarnings("resource")
+ public TcpSocketServer(final int port, final int backlog, final InetAddress localBindAddress, final LogEventBridge<T> logEventInput) throws IOException {
+ this(port, logEventInput, new ServerSocket(port, backlog, localBindAddress));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param port
+ * The port number, or 0 to automatically allocate a port number.
+ * @param logEventInput
+ * the log even input
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ */
+ @SuppressWarnings("resource")
+ public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput) throws IOException {
+ this(port, logEventInput, new ServerSocket(port));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param port
+ * to listen.
+ * @param logEventInput
+ * the log even input
+ * @param serverSocket
+ * the socket server
+ * @throws IOException
+ * if an I/O error occurs when opening the socket.
+ */
+ public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput, final ServerSocket serverSocket)
+ throws IOException {
+ super(port, logEventInput);
+ this.serverSocket = serverSocket;
+ }
+
+ /**
+ * Accept incoming events and processes them.
+ */
+ @Override
+ public void run() {
+ final EntryMessage entry = logger.traceEntry();
+ while (isActive()) {
+ if (serverSocket.isClosed()) {
+ return;
+ }
+ try {
+ // Accept incoming connections.
+ logger.debug("Listening for a connection {}...", serverSocket);
+ @SuppressWarnings("resource") // clientSocket is closed during SocketHandler shutdown
+ final Socket clientSocket = serverSocket.accept();
+ logger.debug("Acepted connection on {}...", serverSocket);
+ logger.debug("Socket accepted: {}", clientSocket);
+ clientSocket.setSoLinger(true, 0);
+
+ // accept() will block until a client connects to the server.
+ // If execution reaches this point, then it means that a client
+ // socket has been accepted.
+
+ final SocketHandler handler = new SocketHandler(clientSocket);
+ handlers.put(Long.valueOf(handler.getId()), handler);
+ handler.start();
+ } catch (final IOException e) {
+ if (serverSocket.isClosed()) {
+ // OK we're done.
+ logger.traceExit(entry);
+ return;
+ }
+ logger.error("Exception encountered on accept. Ignoring. Stack trace :", e);
+ }
+ }
+ for (final Map.Entry<Long, SocketHandler> handlerEntry : handlers.entrySet()) {
+ final SocketHandler handler = handlerEntry.getValue();
+ handler.shutdown();
+ try {
+ handler.join();
+ } catch (final InterruptedException ignored) {
+ // Ignore the exception
+ }
+ }
+ logger.traceExit(entry);
+ }
+
+ /**
+ * Shutdown the server.
+ *
+ * @throws IOException if the server socket could not be closed
+ */
+ @Override
+ public void shutdown() throws IOException {
+ final EntryMessage entry = logger.traceEntry();
+ setActive(false);
+ //Thread.currentThread().interrupt();
+ serverSocket.close();
+ logger.traceExit(entry);
+ }
+}